[firebase-br] LOG via Trigger

Marson Luís marsonluis em gmail.com
Seg Jan 5 16:51:26 -03 2015


Obrigado pela resposta.

Bem, estou usando em um After Update, apenas ... mas, trankilo ... estou
estudando o exemplo que tu fizestes mas, exceto pelo fato de criar/alterar
a trigger de uma tabela, por meio de uma stored procedure chamando um
execute procedure (uso execute statement), o código até que ficou bem
parecido (meio que sem querer) mas, como disse, estou estudando a mesma e
se eu obtiver sucesso, volto a postar aqui. Se não obtiver sucesso, posto
também mas, com certeza, informando o uso do código de sua autoria :-) e,
claro, devidamente creditado ;-)


Em Mon Jan 05 2015 at 16:27:29, Carlos H. Cantu <listas em warmboot.com.br>
escreveu:

> Eu não sei a razão pela qual você decidiu não usar o método
> demonstrado na referida palestra, mas a meu ver o que vc está tentando
> fazer é um retrocesso.
>
> Quanto a exceção, creio que o problema não é o fato de campos não
> terem sido alterados, mas sim o fato de que variáveis NEW e OLD não são
> acessíveis em determinados tipos de trigger. Por exemplo, um trigger
> "before insert" não permite referenciar variáveis OLD.
>
> Sugiro tb que vc estude como funciona o tratamento de exceções no
> PSQL (WHEN...DO).
>
> []s
> Carlos H. Cantu
> www.FireBase.com.br - www.firebirdnews.org
> www.warmboot.com.br - blog.firebase.com.br
>
> ML> Essa, acho, cabe principalmente ao Cantu.
>
> ML>                 Recebi um material da 7 FDD atribuída ao Cantu que
> ML> exemplifica como criar um log de alterações de tabelas. Como havia a
> ML> necessidade de criar uma pequena coleção de funções (Stored Procedures)
> ML> optei por tentar inovar mas “empaquei” em um problema.
>
> ML>                 Veja o código a baixo:
>
>
>
> ML> [SQL]
>
> ML> /* Crio um FOR para os campos da tabela */
>
> ML>   for select RF.RDB$FIELD_NAME CAMPO
>
> ML>       from RDB$RELATION_FIELDS RF
>
> ML>       inner join RDB$FIELDS F on (F.RDB$FIELD_NAME =
> RF.RDB$FIELD_SOURCE)
>
> ML>       where (RF.RDB$RELATION_NAME = '<NOME_DA_TABELA>')
>
> ML>       order by RF.RDB$FIELD_POSITION
>
> ML>       into :VCAMPO
>
> ML>   do
>
> ML>   begin
>
> ML> /* Crio as variáveis CONTEXT*/
>
> ML>     VTEXTOSQL = 'select RDB$SET_CONTEXT(''USER_SESSION'',
> ''OLDVALOR'',
> ML> coalesce(old.' || trim(:VCAMPO) || ', 0)) from rdb$database';
>
> ML>     execute statement :VTEXTOSQL;
>
>
>
> ML>     VTEXTOSQL = 'select RDB$SET_CONTEXT(''USER_SESSION'',
> ''NEWVALOR'',
> ML> coalesce(new.' || trim(:VCAMPO) || ', 0)) from rdb$database';
>
> ML>     execute statement :VTEXTOSQL;
>
>
>
> ML> /* Comparo o conteúdo */
>
> ML>     if (RDB$GET_CONTEXT('USER_SESSION', 'NEWVALOR') <>
> ML> RDB$GET_CONTEXT('USER_SESSION', 'OLDVALOR')) then
>
> ML>     begin
>
> ML>       if (:VLISTACAMPOS = '') then
>
> ML>       begin
>
> ML>         VLISTACAMPOS = 'CAMPO(S) ';
>
> ML>       end
>
> ML>       else
>
> ML>       begin
>
> ML>         VLISTACAMPOS = :VLISTACAMPOS || ', ';
>
> ML>       end
>
> ML>       VLISTACAMPOS = :VLISTACAMPOS || trim(:VCAMPO) || ' DE ' ||
> ML> RDB$GET_CONTEXT('USER_SESSION', 'OLDVALOR') || ' PARA ' ||
> ML> RDB$GET_CONTEXT('USER_SESSION', 'NEWVALOR');
>
> ML>     end
>
>
>
> ML> /* Tento evitar a exceção caso o SET_CONTEXT tente acessar um campo
> que não
> ML> possui alteração */
>
> ML>     when any do
>
> ML>     begin
>
> ML>     end
>
> ML>   end
>
>
>
> ML>   ... Executo o INSERT na tabela de LOG com o obtido no código a cima
>
> ML> [/SQL]
>
>
>
> ML>                 Aí vem o meu problema: o código “WHEN ANY DO ...”
> parece
> ML> matar tudo o que foi feito ...
>
> ML>                 Eu só queria, dinamicamente, comparar o antes e depois
> de
> ML> cada campo mas, como o acesso a um campo não alterado tem me causado
> ML> exceção, resolvi ignorá-las mas, daí, :VLISTACAMPOS que deveria ter a
> lista
> ML> das alterações acabou “sumindo” ...
>
> ML>                 Alguém, ou o próprio Cantu, tem alguma idéia para
> ML> solucionar isso? Se é possível solucionar?
>
>
>
> ML>                 Grato,
>
> ML> Márson de Paula
> ML> ______________________________________________
> ML> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> ML> Para saber como gerenciar/excluir seu cadastro na lista, use:
> ML> http://www.firebase.com.br/fb/artigo.php?id=1107
> ML> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa



Mais detalhes sobre a lista de discussão lista