[firebase-br] LOG via Trigger
Carlos H. Cantu
listas em warmboot.com.br
Seg Jan 5 16:26:20 -03 2015
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
Mais detalhes sobre a lista de discussão lista