Grande William,

Obrigado pela informação sobre o NEW x OLD, realmente não imaginei que o 
comportamento dessas variáveis fosse tão excêntrico. Minha rotina funcionava 
pelos critérios do Oracle, que cria um OLD e um NEW em qualquer tipo de 
trigger, deixando a variável nula caso não se aplique. Não sabia desse tal 
de TG_OP, isolado num canto remoto do manual, obrigado pela dica!
Sobre suas sugestões: implementei uma trigger para INSERT, outra para UPDATE 
e outra para DELETE, ao menos por enquanto, dispensando a necessidade do 
TG_OP e records temporários. É meio redundante, porém fácil de testar e 
ainda mantém isolada a parte mais complexa da minha regra de negócio numa 
function chamada das três triggers.
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, 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...
* o SQL Server tem uma função pronta para indicar isso, mas não achei nada 
parecido em Postgres;
* no Oracle minha solução foi marcar e consultar uma tabela temporária 
(GLOBAL TEMPORARY TABLE) que isola automaticamente uma transação da outra e 
indica quando eu entro ou saio da trigger. Não achei meio de inserir 
registros numa tabela temporária sem que uma transação afete a outra, nem 
achei meios de identificar quais registros são da minha sessão e quais 
pertencem a outras sessões simultâneas. Seria terrível serializar transações 
nessa tabela, logo preciso de uma opção que permita atualizações 
concorrentes;
* Não consegui implementar nenhuma dessas opções em Postgres ainda, logo 
minhas funções ora acabam em chave duplicada por inserir várias vezes o 
mesmo registro, ora travam num loop infinito por executarem tudo novamente a 
cada UPDATE.

Alguma sugestão de próximo passo?

Mozart Hasse

> Troquei todas as referências a minha tabela dentro das functions por
> "public.mvtoestq" ou "gestao.mvtoestq". O problema é que, quando eu chego
> num
> comando DELETE dentro de uma function chamada pela trigger, o Postgres
> reporta
> o erro "ERROR: record 'new' is not assigned yet The tuple structure of a
> not-yet-assigned record is indeterminate. ...".

     Sinto muito, mas realmente ele está certo. Não existe variável "NEW" em
um gatilho de DELETE. Somente OLD, assim como não existe OLD em um gatilho
de INSERT.

      Sugestão 1: veja qual o tipo de gatilho disparou o mesmo: TG_OP ilike
'delete'
      Sugestão 1.1: crie uma variável do tipo da tabela e atribua OLD ou NEW
para a mesma.
       (...)
                 DECLARE ref tabela%ROWTYPE;
                 BEGIN
                          IF TG_OP ILIKE 'DELETE' THEN
                                ref := OLD;
                          ELSE ref := NEW;
                  END IF;
        (...)

Obs.: Não sei dizer se a atribuição é por cópia ou valor. Ou seja, não sei
dizer se, caso atribua NEW para a variável, se o valor será alterado na
tupla que o mesmo representa. Mas caso teste essa solução, por favor, diga
se funciona...


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

Responder a