[firebase-br] Perda de dados depois de certo tempo...

Jeferson Oliveira jefersonfoliveira em gmail.com
Seg Mar 26 21:37:25 -03 2007


> seria de mais te pedir para me
> passar um pequeno ex de como fazer este log. na triggers?

Não.

Montei uma estrutura aqui agora. É um código básico, mas creio que
seja o suficiente para o que você precisa no momento. Criei uma tabela
LOG_EXCLUIDOS. Para cada tabela que você deseja gravar o LOG você deve
inserir a trigger especificada no script, substituindo SuaTabela pelo
nome da tabela em questão.
Segue o script:

/* Início do script*/

/*Cria tabela para armazenar informações sobre os registros excluídos*/
create generator GEN_LOG_EXCLUIDOS_ID;

create table LOG_EXCLUIDOS (
    ID                  integer not null,
    DATA_HORA_EXCLUSAO  date not null,
    NOME_TABELA         varchar(31) not null,
    REGISTRO            varchar(4096)
);
alter table LOG_EXCLUIDOS add constraint PK_LOG_EXCLUIDOS primary key (ID);

set term ^ ;

create trigger LOG_EXCLUIDOS_BI for LOG_EXCLUIDOS
active before insert position 0
as
begin
  if (new.ID is null) then
    new.ID = gen_id(GEN_LOG_EXCLUIDOS_ID,1);
end
^

set term ; ^



/* Cria trigger na tabela SuaTabela para gravar o log dos registros excluídos */
set term ^ ;

create trigger TR_LOG_EXCLUIDOS for SuaTabela
active after delete position 0
as
declare variable TABELA varchar(31);
declare variable NOME_CAMPO varchar(31);
declare variable VALOR_CAMPO varchar(1024);
declare variable TIPO varchar(31);
declare variable SEPARADOR varchar(10);
declare variable REGISTRO varchar(4096);
begin
  SEPARADOR = '  %|%|%  ';  -- um string de sua preferencia para
separar os campos
  TABELA = 'SuaTabela';
  REGISTRO = '';
  for
    select F.RDB$FIELD_NAME as CAMPO,
           case T.RDB$TYPE_NAME
             when 'VARYING' then 'VARCHAR'
             when 'LONG' then 'INTEGER'
             when 'TEXT' then 'CHAR'
             when 'TIMESTAMP' then 'DATE'
             when 'DOUBLE' then
               case when FS.RDB$FIELD_SCALE < 0 then
                 'NUMERIC'
               else
                 'DOUBLE PRECISION' end
           else
             RDB$TYPES.RDB$TYPE_NAME end as TIPO
    from RDB$RELATION_FIELDS F
    join RDB$FIELDS FS
      on FS.RDB$FIELD_NAME = F.RDB$FIELD_SOURCE
    join RDB$TYPES T
      on FS.RDB$FIELD_TYPE = T.RDB$TYPE
     and T.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
    where F.RDB$RELATION_NAME = :TABELA
    order by F.RDB$FIELD_POSITION
   into :NOME_CAMPO, :TIPO do
   begin
     /*
       Para simplificar a trigger, não serão armazenados valores de campos BLOB,
       devido à dificuldade de manipulação
       desse tipo de dado diretamente pelo Firebird
     */
     if (:TIPO <> 'BLOB') then
     begin
       /*
         como o Firebird não permite obter um valor de um campo dinamicamente,
         através de algo como old.'NomeCampo', é necessário realizar um teste
         para cada campo da tabela que considerar importante armazenar no log.
       */
       VALOR_CAMPO = '';
       if (NOME_CAMPO = 'BAIXA_MATPRIMA') then
         VALOR_CAMPO = cast(old.BAIXA_MATPRIMA as varchar(1024));

       if (NOME_CAMPO = 'SETOR_GERA_ETQ') then
         VALOR_CAMPO = cast(old.SETOR_GERA_ETQ as varchar(1024));

       REGISTRO = :REGISTRO || :NOME_CAMPO || ': ' || :VALOR_CAMPO ||
:SEPARADOR;
     end
   end
   insert into LOG_EXCLUIDOS
   (NOME_TABELA, DATA_HORA_EXCLUSAO, REGISTRO)
   values
   (:TABELA, current_timestamp, :REGISTRO);
end
^


set term ; ^

/* Fim do script*/


Espero que isso lhe ajude. Mande notícias. :)


Abraço!
Jeferson Oliveira




Mais detalhes sobre a lista de discussão lista