[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