[firebase-br] RES: RES: Auto Imcremento no FireBird e DB Express

Reuber jubrovolski em yahoo.com.br
Qua Set 12 11:47:53 -03 2007


Olá Vinícius

Não me lembro o autor dessa rotina, mas sei que é uma mão na roda pra 
mim. Nunca mais tive que me preocupar com autoincremento no firebird.
Fiz algumas adaptações, para me atender. Se achar válido, o Cantú 
poderia colocar no site da firebase. Vamos lá:

Crie 2 tabelas, eis as estruturas.

***[ TABELA 1 ]*************************************************
CREATE TABLE USERS_SEQUENCIA (
     SEQUENCIA_TABELA  CHAR(100) NOT NULL,
     SEQUENCIA_CAMPO   CHAR(30) NOT NULL,
     SEQUENCIA_VALOR   INTEGER
);

ALTER TABLE USERS_SEQUENCIA ADD CONSTRAINT PK_USERS_SEQUENCIA PRIMARY 
KEY (SEQUENCIA_TABELA, SEQUENCIA_CAMPO);

COMMENT ON TABLE USERS_SEQUENCIA IS
'Sequência de AutoNumeração de Campos';

***[ TABELA 2 ]*************************************************

CREATE TABLE USERS_SEQPEND (
     SEQUENCIA_TABELA  CHAR(100) NOT NULL,
     SEQUENCIA_CAMPO   CHAR(30) NOT NULL,
     PENDENCIA_VALOR   INTEGER NOT NULL
);



ALTER TABLE USERS_SEQPEND ADD CONSTRAINT PK_USERS_SEQPEND PRIMARY KEY 
(SEQUENCIA_TABELA, SEQUENCIA_CAMPO, PENDENCIA_VALOR);


ALTER TABLE USERS_SEQPEND ADD CONSTRAINT FK_USERS_SEQPEND_2 FOREIGN KEY 
(SEQUENCIA_TABELA, SEQUENCIA_CAMPO) REFERENCES USERS_SEQUENCIA 
(SEQUENCIA_TABELA, SEQUENCIA_CAMPO) ON DELETE CASCADE;


COMMENT ON TABLE USERS_SEQPEND IS
'Sequência Perdida de AutoNumeração de Campos';


/******************************************************************************/


Agora Crie a procedure:



SET TERM ^ ;

CREATE PROCEDURE USERS_PSEQUENCIA (
     TABELA VARCHAR(50),
     CAMPO VARCHAR(20),
     PENDENCIA INTEGER,
     VALORATUAL CHAR(10))
RETURNS (
     ID_RETORNO INTEGER)
AS
DECLARE VARIABLE MAXID INTEGER;
DECLARE VARIABLE ID_SEQUENCIA INTEGER;
BEGIN
   ID_SEQUENCIA = 0;
   MAXID = 0;
   /* Inclui uma Nova Pendencia na Tabela de Pendencias */
   if (PENDENCIA = 1) then
     begin
       if (not(exists(SELECT SEQUENCIA_VALOR
          FROM USERS_SEQUENCIA
          WHERE SEQUENCIA_TABELA = :TABELA
          AND SEQUENCIA_CAMPO    = :CAMPO))) then
         begin
           EXECUTE STATEMENT 'SELECT COALESCE(MAX('||CAMPO||'),1) from 
'|| tabela into :maxid;
           if (maxid <> 0) then
              begin
              INSERT INTO USERS_SEQUENCIA VALUES(:TABELA , :CAMPO , 
:maxid+2);
              end
           else
              begin
              INSERT INTO USERS_SEQUENCIA VALUES(:TABELA , :CAMPO , 2);
              end
         end
       INSERT INTO USERS_SEQPEND
       VALUES(:TABELA ,:CAMPO ,:VALORATUAL);
       SUSPEND;
       exit;
     end
   if (exists(SELECT PENDENCIA_VALOR
              FROM USERS_SEQPEND
              WHERE SEQUENCIA_TABELA = :TABELA
              AND SEQUENCIA_CAMPO    = :CAMPO)) then
     begin
       FOR SELECT PENDENCIA_VALOR
       FROM USERS_SEQPEND
       WHERE SEQUENCIA_TABELA = :TABELA
       AND SEQUENCIA_CAMPO = :CAMPO
       ORDER BY PENDENCIA_VALOR DESC
       INTO :ID_SEQUENCIA DO
         BEGIN
           ID_RETORNO = :ID_SEQUENCIA;
         END
     end
   else
     ID_SEQUENCIA = 0;

   if (ID_SEQUENCIA <> 0) then
     begin
       ID_RETORNO = :ID_SEQUENCIA;
       DELETE FROM USERS_SEQPEND
       WHERE SEQUENCIA_TABELA = :TABELA
       AND SEQUENCIA_CAMPO    = :CAMPO
       AND PENDENCIA_VALOR    = :ID_SEQUENCIA;

       SUSPEND;
       exit;
     end
   else
     begin

       if (not(exists(SELECT SEQUENCIA_VALOR
          FROM USERS_SEQUENCIA
          WHERE SEQUENCIA_TABELA = :TABELA
          AND SEQUENCIA_CAMPO    = :CAMPO))) then
         begin
           EXECUTE STATEMENT 'SELECT MAX('||CAMPO||') from '|| tabela 
into :maxid;
           if (maxid <> 0) then
              begin
              INSERT INTO USERS_SEQUENCIA VALUES(:TABELA , :CAMPO , 
:maxid+2);
              ID_RETORNO = :maxid+1;
              end
           else
              begin
              INSERT INTO USERS_SEQUENCIA VALUES(:TABELA , :CAMPO , 2);
              ID_RETORNO = 1;
              end
         end
       else
         begin
           SELECT SEQUENCIA_VALOR
           FROM USERS_SEQUENCIA
           WHERE SEQUENCIA_TABELA = :TABELA
           AND SEQUENCIA_CAMPO    = :CAMPO
           INTO :ID_SEQUENCIA;

           UPDATE USERS_SEQUENCIA
           SET SEQUENCIA_VALOR = SEQUENCIA_VALOR + 1
           WHERE SEQUENCIA_TABELA = :TABELA
           AND SEQUENCIA_CAMPO    = :CAMPO;

           ID_RETORNO = :ID_SEQUENCIA;
         end

     end

  SUSPEND;
END^

SET TERM ; ^

*********************************************************

// usando um componente TSQLStoreProcedure no delphi


function idSimples(const tabela: String; const campo: String; const 
pendencia: Integer; const valoratual: String): String;
begin
   with stpidsimples do begin
         Parambyname('TABELA').asstring     := UPPERCASE(TABELA);
         Parambyname('CAMPO').asstring      := UPPERCASE(CAMPO);
         Parambyname('PENDENCIA').asinteger := Pendencia;
         Parambyname('VALORATUAL').asstring := ValorAtual;
           ExecProc;
         Result := Parambyname('ID_RETORNO').asstring;
   end;
end;

// para pegar o autoincremento

clientdataset1.FieldByName(campo).value := 
idsimples(tabelanobd,camponobd, 0,'');

// quando deletar um regitro e quiser "guardar" a chave
vvalorcampo:=clientdataset1.fieldbyname(campochave).value;
clientdataset1.delete;
clientdataset1.ApplyUpdates(0);
idsimples(tabelanobd , camponobd, 1,vvalorcampo);

// após o cancelamento do registro se não for alteração.

  if (clientdataset1.State in [dsinsert]) and 
(clientdataset1.fieldbyname(campochave).AsString <> '') then
idsimples(tabelanobd , camponodb, 1, 
clientdataset1.FieldByname(campo).asstring);
clientdataset1.cancel;

**********************

Espero que ajude

Reuber



.::Vinícius Mesquita:@smtp.bol.com.br:. escreveu:
> Amigos alguém teria o código do super seqüenciador?
> 
> Grato!





Mais detalhes sobre a lista de discussão lista