[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