------ Original Message ------
> From: " William Leite Araújo "        <[EMAIL PROTECTED]>
> 
> 2008/9/17 Mozart Hasse <[EMAIL PROTECTED]>
> 
> > (...)
> > Atribuir o NEW nas triggers de BEFORE até que aparentemente funcionou,
> > porém
> > tive de deixar todas as triggers como AFTER para resolver outros
> > problemas...
> 
> 
>     Bom, novamente vou alertar que NUNCA, no postgresql, atribuir valores
ao
> registro NEW ou OLD num gatilho "AFTER" funcionará. A idéia do AFTER é
fazer
> alterações em outras tabelas, e não na que gerou o evento.

Sim, eu sei, troquei as atribuições por UPDATES diretos na tabela ao passar
para triggers AFTER.


> > Bom, a coisa até que andou, não tenho mais aquele erro do "record 'new'
is
> > not assigned yet", só que agora resta descobrir como se implementa em
> > Postgres a funcionalidade da qual as triggers originais dependiam:
> > identificar se a chamada atual da trigger function foi disparada de um
> > UPDATE/INSERT/DELETE da aplicação ou da própria trigger...
> 
>       Tive problemas com isso uma vez, e acho que uma possivel solução
seria
> marcar isso numa tabela temporária pela regra da VIEW. É possível
executar
> mais de uma ação na regra.
>  Por exemplo:
> 
>   CREATE RULE regra_do_cao ON INSERT TO [nome da view] DO INSTEAD *(*
>      INSERT INTO [tabela temporaria de marcação] VALUES (...);
>      INSERT INTO [tabela real] VALUES (...) *);*

O problema é que eu tenho de marcar a tabela temporária de _dentro_ da
trigger... 

Explicando melhor: eu preciso fazer, por conta do mesmo comando de origem,
duas coisas:

* ajustar ponteiros dos registros anterior, atual e posterior. A trigger
function pode alterar registros (incluindo o registro original) por conta da
operação original, e essas alterações não devem disparar novamente a
trigger (ou pelo menos devem notar que é uma chamada recursiva e sair sem
fazer nada);

* depois de garantir que os ponteiros estão em ordem, eu tenho de disparar
uma function (recálculo de registros posteriores) uma única vez a cada
comando 'externo' à trigger, e isso só pode acontecer _depois_ de atualizar
o registro original. Esta function pode incluir, alterar e excluir registros
por conta da operação original. Essas operações não devem disparar
novamente a própria function. 

O desejável seria que as atualizações da function de recálculo se
aproveitassem da parte de atualização de ponteiros das trigger functions,
pois há diversos pontos de atualização e a função depende da integridade
dos ponteiros após cada operação. A replicação dessa regra em cada um dos
lugares em que a tabela é atualizada tornaria o código horrivelmente
complicado, absurdamente redundante e radicalmente difícil de manter.

Eu atualizo a tabela de marcação em Oracle na primeira atualização
proveniente de qualquer trigger, a fim de saber que as chamadas subsequentes
devem ser ignoradas ou devem fazer apenas as operações que não causam
recursão.

Se eu entrar na trigger com a tabela já marcada (conforme sua sugestão),
não vou saber quando posso e quando não posso atualizar os registros
anteriores e posteriores ou disparar a rotina de recálculo.
Se eu puser a chamada dessa rotina de recálculo como comando posterior à
atualização do registro na declaração da RULE, ainda assim terei problemas
com a recursividade, pois os comandos da trigger e da function de recálculo
vão disparar as triggers eternamente.

Bom, eu poderia tentar tirar tudo das triggers e fazer rules que chamam um
monte de functions numa certa sequência, o que teoricamente acabaria com o
problema da recursividade. A questão é... não tem um jeito mais simples ?!

Grato pela atenção,

Mozart Hasse


_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a