Duvida no uso trigger no Oracle?

1 resposta
P

Ola´,

Peguei esse exemplo abaixo sobre trigger e sempre uso com FOR EACH ROW,
para cada linha a uma ação até ai tudo bem …

E deparei com o exemplo abaixo e setença

Observe que a mensagem 'O USUÁRIO ALTEROU...' será cadastrada na tabela de log apenas uma vez, independente da quantidade de registros alterados

não entendi porque será incluida apenas uma vez …???

outra duvida quando não uso FOR EACH ROW não consigo utilizar as variaveis old e new ???

abs

CREATE OR REPLACE TRIGGER LOG_UPDATE_FUNCIONARIO

 BEFORE UPDATE ON FUNCIONARIO

 BEGIN

     INSERT INTO LOGOPERACAO

       (IDLOGOPERCAO, USUARIO, DATA, DESCRICAO)

     VALUES

       (SEQLOGOPERACAO.NEXTVAL, USER, SYSDATE, 'O USUÁRIO ALTEROU REGISTROS  NA TABELA');

 END;

 

         Note que a ausência da frase ?FOR EACH ROW? caracteriza a trigger como statement-level. Para testar, execute o comando:

 

 UPDATE FUNCIONARIO SET SALARIO = SALARIO * 1.1;

SELECT * FROM LOGOPERACAO;

Observe que a mensagem 'O USUÁRIO ALTEROU...' será cadastrada na tabela de log apenas uma vez, independente da quantidade de registros alterados. Um fato interessante é que a trigger row-level UPDATE_FUNCIONARIO, criada anteriormente, continua ativa, inserindo ocorrências na tabela de log para registro alterado.
/* Trigger para log o Update */

 

CREATE OR REPLACE TRIGGER UPDATE_FUNCIONARIO

BEFORE UPDATE ON FUNCIONARIO

FOR EACH ROW

DECLARE

  sDecricao VARCHAR2(1000);

  bAlterouRegistro Boolean := False;

BEGIN

  sDecricao := '';

  IF :NEW.IDFUNCIONARIO <> :OLD.IDFUNCIONARIO THEN

     sDecricao := sDecricao || ' Campo: IDFUNCIONARIO' ||

                               ' Valor Atual: ' || :NEW.IDFUNCIONARIO ||    

                               ' Valor Anterior: ' || :OLD.IDFUNCIONARIO;

     bAlterouRegistro := True;

  END IF;

  IF :NEW.NOMEFUNCIONARIO <> :OLD.NOMEFUNCIONARIO THEN

     sDecricao := sDecricao || ' Campo: NOMEFUNCIONARIO' ||

                             ' Valor Atual: ' || :NEW.NOMEFUNCIONARIO ||    

                             ' Valor Anterior: ' || :OLD.NOMEFUNCIONARIO;

     bAlterouRegistro := True;

  END IF;

  IF :NEW.SALARIO <> :OLD.SALARIO THEN

     sDecricao := sDecricao || ' Campo: SALARIO' ||

                               ' Valor Atual: ' || :NEW.SALARIO ||    

                               ' Valor Anterior: ' || :OLD.SALARIO;

     bAlterouRegistro := True;

  END IF;

  IF :NEW.FLGGERENTE <> :OLD.FLGGERENTE THEN

     sDecricao := sDecricao || ' Campo: FLGGERENTE' ||

                               ' Valor Atual: ' || :NEW.FLGGERENTE ||    

                               ' Valor Anterior: ' || :OLD.FLGGERENTE;

     bAlterouRegistro := True;

  END IF;

 

  IF bAlterouRegistro THEN

    sDecricao := 'Alteração da Tabela Funcionario' || sDecricao;

    INSERT INTO LOGOPERACAO

      (IDLOGOPERCAO, USUARIO, DATA, DESCRICAO)

    VALUES

      (SEQLOGOPERACAO.NEXTVAL, USER, SYSDATE, sDecricao);

  END IF;

END;

 

/* Trigger para log do Delete */

 

CREATE OR REPLACE TRIGGER DELETE_FUNCIONARIO

AFTER DELETE ON FUNCIONARIO

FOR EACH ROW

DECLARE

  sDecricao LOGOPERACAO.DESCRICAO%type;

BEGIN

  sDecricao := 'Exclusão da Tabela Funcionario' ||

               ' Campo: IDFUNCIONARIO' ||

               ' Valor: ' || :OLD.IDFUNCIONARIO ||

               ' Campo: NOMEFUNCIONARIO' ||

               ' Valor: ' || :OLD.NOMEFUNCIONARIO ||

               ' Campo: SALARIO' ||

               ' Valor: ' || :OLD.SALARIO ||

               ' Campo: FLGGERENTE' ||

               ' Valor: ' || :OLD.FLGGERENTE;

 

  INSERT INTO LOGOPERACAO

    (IDLOGOPERCAO, USUARIO, DATA, DESCRICAO)

  VALUES

    (SEQLOGOPERACAO.NEXTVAL, USER, SYSDATE, sDecricao);

END;

1 Resposta

C

O Oracle tem duas categorias de trigger: ou por linha alterada/incluida/deletada, ou por comando insert/update/delete executado.
Isto é útil qndo vc tem que gerar informações de categorização de outras informações, verificação de acesso

Criado 27 de junho de 2009
Ultima resposta 29 de jun. de 2009
Respostas 1
Participantes 2