Fórum Dúvida sobre triggers #49563

24/02/2005

0

Olá! Estava tentando descobrir o momento exato em que os triggers eram executados pelo Firebird 1.5. Criei então um banco de dados teste com uma tabela ´teste´ com quatro triggers: before_insert, after_insert, before_update e after_update. Cada um desses triggers ao serem executados postavam um evento com o nome do trigger, ou melhor, o trigger before_update executava: ´POST_EVENT ´before_update´´ e assim por diante. Criei um projeto com um IBDatabase e coloquei no form um IBEvents. No OnCreate do formulário eu abro o banco de dados e registro os eventos do IB_Events. No evento OnEventAlert eu fiz com que ele adicionasse o nome do evento em um memo com a Data/Hora em que a linha estava sendo adicionada e um número sequencial para eu ter certeza de que o memo não estava reordenando os registros. Em um botão do form eu executava em uma IBSQL um INSERT na tabela. Em outro botão eu executava um UPDATE no registro que eu inseri. Para minha surpresa, o memo ficou da seguinte maneira:

1 - after_insert;
2 - before_insert;
3 - after_update;
4 - before_update;

Vendo isso fiquei muito confuso, afinal, por que o evento after_insert aconteceu antes do before_insert? E a mesma coisa para os triggers de Update? Alguém saberia se isso é realmente o normal? E no final das contas, quando é que é disparado cada um dos triggers?

Até!


Delphi32

Delphi32

Responder

Posts

24/02/2005

Afarias

BEFORE sempre ocorre antes de AFTER (como era de se esperar)

o efeito q vc está vendo é devido a velocidade entre a ocorrência das triggers no servidor e a natureza do sistema de eventos.

para tirar a prova, faça o seginte teste::

crie uma tabela qualquer onde vc fará o teste, exemplo:

create table teste (valor integer);


então crie uma segunda tabela, para fazer um LOG das operações:

create table log (valor integer, data timestamp, op char(2));


então crie as triggers (vou colocar apenas as de insert):

set term ^

create trigger log1 for teste before insert as
begin
  insert into log values (new.valor, cast(´now´ as timestamp), ´BI´);
end^

create trigger log2 for teste after insert as
begin
  insert into log values (new.valor, cast(´now´ as timestamp), ´AI´);
end^

set term ;^


então insira um valor na tebala teste:

insert into teste values (1);


e liste os valores da tabela de log:

select * from log order by data;


vc vai notar q não há como ordenar por data pq o processamento foi tão rápido q as datas estão exatamente iguais (mesmo os milisegundos) -- a não ser q vc adicione algum processamento extra na trigger before insert, não tem como perceber a distinção...

...a não ser... espere ai... nós temos o campo rdb$db_key q pode ser a solução para este problema (se não conhece este campo, pesquise neste fórum sobre ele), então vamos fazer:

select rdb$db_key, valor, data, op from teste;


quanto menor o rdb$db_key mais antigo é o registro (bom, neste caso pelo menos... a coisa é um pouquinho mais ´complexa´ q isso), agora sim... vc vai notar q o evento BI ocorre ANTES do evento AI

:)


T+


Responder

Gostei + 0

10/05/2005

Crash

Eu tambem estou tendo esse mesmo problema... eu mando um post_event no after_update e qdo recebo o evento eu mando fechar e abrir a tabela novamente. Qdo ela abre está com os dados antigos ainda. E outra.. eu ja tentei dar um sleep ou application.processmessages e nao adianta.

t+


Responder

Gostei + 0

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

Aceitar