2008/9/18 Mozart Hasse <[EMAIL PROTECTED]>
>
>
> ------ 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);
Nesse sentido, existe a possibilidade de desabilitar o trigger durante a
execução do mesmo (caso o usuário tenha essa permissão ou o trigger seja
"SECURITY DEFINNER"). Tipo :
ALTER TABLE [tabela] DISABLE TRIGGER xxx;
(... comandos pra fazer as alterações ...)
ALTER TABLE [tabela] ENABLE TRIGGER xxx;
Não sei dizer se desabilitará para todas as transações (acredito que
não) ou somente para a corrente.
>
>
> * 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.
Bom, essa function (por ser apenas uma) pode então iniciar seu
processamento marcando em uma tabela temporária que está em execução para
evitar que ela seja novamente executada, certo?
>
>
> 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.
>
Concordo. Que coisa mais "louca"...
>
> 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.
>
E isso não funciona com o Postgresql, numa tabela temporária? O nome da
tabela temporária pode conter, por exemplo, o ID da transaçã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 ?!
>
Acho que não resolveria o problema. Apenas mudaria o ponto onde ele
ocorreria...
--
William Leite Araújo
Analista de Banco de Dados - QualiConsult
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral