Fórum Auto incremento #57356

02/12/2006

0

Olá amigos, boa noite

Preciso da ajuda de vocês com uma questão sobre autoincremento
A situação é a seguinte , criei um trigger para calcular o campo codcli e fazer seu autoincremento , segue p código da trigger e do generator:

create generator inc_codcli;


create trigger tb_Cliente for cliente
active before insert position 0
as
begin
if (new.codcli is null) then
new.codcli = gen_id (inc_codcli,1);
end


Está funcionando PERFEITAMENTE, faz exatamente o que deveria. A minha dúvida é sobre o seguinte:

Imaginemos que eu tenha 10 registros na tabela e delete 3 deles, quando eu inserir um novo ele será o codcli 11 pois o generator está setado para 11, como fazer o generator verificar o maior valor do campo códcli e receber este valor para que ao rodar a trigger o codigo seja corretamente o valor 8?

Obrigado a todos desde já


Zoom

Zoom

Responder

Posts

04/12/2006

Emerson Nascimento

crieo que nesse caso você não poderá trabalhar com generator´s. terá de fazer a coisa na mão:
create trigger tb_Cliente for cliente
active before insert position 0
as
begin
if (new.codcli is null) then
new.codcli = (select coalesce(max(codcli),0)+1 from tb_Cliente);
end
assim o generator nem será necessário, podendo até ser ´dropado´


Responder

Gostei + 0

05/12/2006

Martins

Desculpem eu meter minha colher aqui, pois sou um mero aprendiz professores, mas não corre o risco de gerar um código que já existe?

Tipo.
ID_CLI  NOME_CLI
1           MARIA
2           JOAO
3           MARCOS
4           AURÉLIO
5           JONAS
6           THIAGO
//
Se eu deletar os três últimos registros e depois incrementar novamente vai dar certo, mas se eue deletar digamos (2, 4 e 5) eu terei ficado com 03 (três) registros não é isso, então incrementando novamente apartir do maior código existente que seria o 06 (seis) eu teria (7,...) não seria isso?
Se não for assim, podem me explicar como funcionaria então, pq isso é interessante, não deixar brechas na sequencia númerica dos códigos.

valew!!



Responder

Gostei + 0

05/12/2006

Emerson Nascimento

Martins, da forma como eu passei esse risco não existe, porque a instrução trará o maior valor de registro acrescido de 1, então, se você excluiu os registros 2, 4 e 5, ainda assim o novo registro gerado seria o 7, pois seria o maior (6) acrescido de 1.

mas o que o Martins mostrou é um caso muito comum. Quando houver exclusão de registros intermediários, ficará, sim, uma ´brecha´ entre os registros.

e, pra falar a verdade, eu nunca entendi muito porque a preocupação com o ID gerado para os registros. ele deveria ter usado internamente, transparente ao usuário.


Responder

Gostei + 0

05/12/2006

Martins

Martins, da forma como eu passei esse risco não existe, porque a instrução trará o maior valor de registro acrescido de 1, então, se você excluiu os registros 2, 4 e 5, ainda assim o novo registro gerado seria o 7, pois seria o maior (6) acrescido de 1. mas o que o Martins mostrou é um caso muito comum. Quando houver exclusão de registros intermediários, ficará, sim, uma ´brecha´ entre os registros. e, pra falar a verdade, eu nunca entendi muito porque a preocupação com o ID gerado para os registros. ele deveria ter usado internamente, transparente ao usuário.


Ok [b:126b8f3738]Emerson.en[/b:126b8f3738], entendi agora meu amigo e concordo com vc quanto ao ID.

valew


Responder

Gostei + 0

05/12/2006

Martins

Martins, da forma como eu passei esse risco não existe, porque a instrução trará o maior valor de registro acrescido de 1, então, se você excluiu os registros 2, 4 e 5, ainda assim o novo registro gerado seria o 7, pois seria o maior (6) acrescido de 1. mas o que o Martins mostrou é um caso muito comum. Quando houver exclusão de registros intermediários, ficará, sim, uma ´brecha´ entre os registros. e, pra falar a verdade, eu nunca entendi muito porque a preocupação com o ID gerado para os registros. ele deveria ter usado internamente, transparente ao usuário.


Ok [b:089dc51585]Emerson.en[/b:089dc51585], entendi agora meu amigo e concordo com vc quanto ao ID.

valew


Responder

Gostei + 0

05/12/2006

Martins

Martins, da forma como eu passei esse risco não existe, porque a instrução trará o maior valor de registro acrescido de 1, então, se você excluiu os registros 2, 4 e 5, ainda assim o novo registro gerado seria o 7, pois seria o maior (6) acrescido de 1. mas o que o Martins mostrou é um caso muito comum. Quando houver exclusão de registros intermediários, ficará, sim, uma ´brecha´ entre os registros. e, pra falar a verdade, eu nunca entendi muito porque a preocupação com o ID gerado para os registros. ele deveria ter usado internamente, transparente ao usuário.


Ok [b:d0c684b3ad]Emerson.en[/b:d0c684b3ad], entendi agora meu amigo e concordo com vc quanto ao ID.

valew


Responder

Gostei + 0

05/12/2006

Adriano_servitec

Olah Emerson, tentei criar uma Trigger assim como vc postou no IBExpert, mais nao gera da erro de script

CREATE TRIGGER CORRENTE_BI0 FOR CORRENTE
ACTIVE BEFORE INSERT POSITION 0
as
begin 
if (new.sequencia2 is null) then
new.sequencia2 = (select coalesce(max(sequencia2),0)+1 from CORRENTE_BI0);
end


Nao pode criar esta nova trigger no before insert do ibexpert?


Responder

Gostei + 0

05/12/2006

Emerson Nascimento

CREATE TRIGGER CORRENTE_BI0 FOR CORRENTE
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.sequencia2 is null) then
new.sequencia2 = (select coalesce(max(sequencia2),0)+1 from CORRENTE);
end
note que havia um erro na instrução [i:498be7ccf0]select[/i:498be7ccf0]


Responder

Gostei + 0

06/12/2006

Adriano_servitec

Desculpe a percistencia Emerson, mais nao consegui fazer funcionar
CREATE TRIGGER CORRENTE_BI0 FOR CORRENTE
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  /* Trigger text */
  if (new.sequencia2 is null) then 
new.sequencia2 = (select coalesce(max(sequencia2),0)+1 from CORRENTE); 

end

Erro
Column does not belong to referenced table. Dynamic SQL Error. SQL error code = -206. Subselect illegal in this context.


Bom eu criei este campo chamado [b:0be7c4e944]sequencia2[/b:0be7c4e944] como integer e na aba trigger da tabela dentro do ibexpert no before insert usei a opçao [b:0be7c4e944]New Trigger[/b:0be7c4e944] e coloquei o script do SQL e depois na hora que clico em [b:0be7c4e944]compiler trriger[/b:0be7c4e944] gera o erro acima.


Responder

Gostei + 0

06/12/2006

Emerson Nascimento

ops!!! realmente havia um erro... :oops:

tente assim:
CREATE TRIGGER CORRENTE_BI FOR CORRENTE
ACTIVE BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE NOVASEQUENCIA INTEGER;
BEGIN
  IF (NEW.SEQUENCIA2 IS NULL) THEN
  BEGIN
    SELECT COALESCE(MAX(SEQUENCIA2),0)+1
    FROM CORRENTE INTO :NOVASEQUENCIA;

    NEW.SEQUENCIA2 = NOVASEQUENCIA;
  END
END



Responder

Gostei + 0

06/12/2006

Adriano_servitec

Descobri como eh o correto

AS
begin
  /* Trigger text */
  if (new.sequencia2 is null) then 
  select coalesce(max(sequencia2),0)+1 from CORRENTE into new.sequencia2;

end



Responder

Gostei + 0

06/12/2006

Adriano_servitec

Olah Emerson, agora me surgiu uma duvida, eu postei se ter visto o teu post praticamente eh o mesmo codigo que eu postei com exeçao que foi declarada uma variavel [b:25fee2ed8d]DECLARE VARIABLE NOVASEQUENCIA INTEGER; [/b:25fee2ed8d]

Entao novamente a pergunta

O que eu fiz NAO esta correto?

Lembrando que nao conheço quase nada ainda de trigger


Responder

Gostei + 0

06/12/2006

Emerson Nascimento

o que você postou está correto.
é que eu tenho costume de trabalhar com variáveis, por conta de geralmente fazer mais de uma avaliação com o valor obtido.


Responder

Gostei + 0

06/12/2006

Adriano_servitec

o que você postou está correto. é que eu tenho costume de trabalhar com variáveis, por conta de geralmente fazer mais de uma avaliação com o valor obtido.


Valeu amigo, muito obrigado.

Andei fazendo uns testes aki

Bom primeiro zerei o banco de dados pois a sequencia estava pegado o ultimo do generator, ai fiz uns lançamentos com a nova trriger e ficou na sequencia

1
2
3

ai exclui a sequenca 2
e fiz outro lançamento e ficou assim
1
3
4

a pergunta eh teria como voltar a ficar assim
1
2
3

em vez de
1
3
4

Ou no caso tem algum problema em fazer um retocesso na trigger pois no caso ai o que eh sequencia 3 passa a ser sequencia 2. Nao sei se pode fazer isso sem afetar o banco.

Lembrando que esse campo nao eh nem chave primaria nem chave estrangeira, uso apenas para fazer alguns updates e delete por ele.


Responder

Gostei + 0

06/12/2006

Emerson Nascimento

tem sim. faça uma trigger after delete:
CREATE TRIGGER CORRENTE_DEL FOR CORRENTE
ACTIVE AFTER DELETE POSITION 0
AS
BEGIN
  UPDATE CORRENTE SET SEQUENCIA2 = SEQUENCIA2 - 1
  WHERE SEQUENCIA2 > OLD.SEQUENCIA2;
END

obs.:para tornar a execução mais rápida - tanto dessa trigger quanto da anterior - crie um índice pelo campo sequencia2


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar