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

"=?iso-8859-1?Q?.::Vin=EDcius_Mesquita:" em smtp.bol.com.br "=?iso-8859-1?Q?.::Vin=EDcius_Mesquita:" em smtp.bol.com.br
Qua Set 12 12:28:53 -03 2007


Reuber, 

muito obrigado pela rotina, estou começando a programar e tinha curiosidade
de conhecer o funcionamento do super seqüenciador e em relação as discuções
a respeito da divisão por grau de conhecimento eu acho que talvez seja
desnecessário pois eu assimilo muita coisa com vcs grandes desenvolvedores,
tudo bem que tem perguntas ridículas mas que isso talvez seja o caso de
somente ignorar. E os grandes que não querem expandir o conhecimento aos
outros eu só tenho a dizer que é uma pena! Talvez seja por isso que os
outros países são mais desenvolvidos tecnológicamente.

Abraços e mais uma vez obrigado!


-----Mensagem original-----
De: lista-bounces em firebase.com.br [mailto:lista-bounces em firebase.com.br] Em
nome de Reuber
Enviada em: quarta-feira, 12 de setembro de 2007 09:48
Para: lista em firebase.com.br
Assunto: Re: [firebase-br] RES: RES: Auto Imcremento no FireBird e DB
Express

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!


______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para editar sua configuração na lista, use o endereço
http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
Para consultar mensagens antigas: http://firebase.com.br/pesquisa





Mais detalhes sobre a lista de discussão lista