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
