Em 18/09/08, Mozart Hasse<[EMAIL PROTECTED]> escreveu:
>
>
> ------ 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.
>

Veja a solução proposta pelo Pavel Stehule para evitar chamadas recursivas:
http://www.nabble.com/Synchronize-two-similar-tables%3A-recursive-triggers-to19545281.html


> 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 ?!
>


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

Responder a