[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