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;