Criando Triggers no Oracle

Olá pessoal…

Hoje irei falar um pouco sobre Triggers (Gatilhos) em Oracle, qual a sua funcionalidade e como criar.


Mas o que seria Triggers? Simplesmente são Gatilhos acionados por ações de usuários, por exemplo, ao criar algum registro, atualize tais dados, ou ao excluir, atualize outra tabela. Enfim, basicamente é uma ação disparada por uma outra ação (ex.: ao incluir, faça algo).

Um bom exemplo seria, ao aumentar o salário de uma pessoa, gravar um log com o salário antigo. Esse exemplo que será demonstrado abaixo, primeiramente iremos criar uma tabela de logs, onde qualquer alteração em salários (da tabela padrão EMPLOYEES), irá gerar um registro de Log.
Abaixo, o script para criação da tabela de Logs.

Criando tabela de logs:

CREATE TABLE  Y_LOG (
  ID_LOG          NUMBER(08)   NOT NULL   PRIMARY KEY,
  DATA_LOG        DATE         NOT NULL,
  SALARIO_ANT     NUMBER(08,2) NOT NULL,
  SALARIO_NOV     NUMBER(08,2) NOT NULL,  
  ID_FUNC         NUMBER(06)   NOT NULL
);

Criando sequência de incremento (dúvidas, leia Criando Sequences no Oracle):

CREATE SEQUENCE SEQ_LOG
  START WITH 1
  INCREMENT BY 1
  MAXVALUE 999999999
  MINVALUE 1
  NOCACHE
  NOCYCLE;

Criando Gatilho (que define antes ou depois de qual ação – BEFORE ou AFTER, de qual campo – OF, em qual tabela – ON, e para cada linha – FOR EACH ROW):

CREATE OR REPLACE TRIGGER VERIF_SALARIO
  BEFORE UPDATE
  OF SALARY
  ON EMPLOYEES
  FOR EACH ROW
  BEGIN
  insert into Y_LOG values (    SEQ_LOG.NEXTVAL,
                SYSDATE,
                :old.SALARY,
                :new.SALARY,
                :old.EMPLOYEE_ID);
END;

Não esqueça de salvar os dados.

COMMIT;

Atualizando tabela para criação de Gatilho:

UPDATE EMPLOYEES SET SALARY=24000 WHERE EMPLOYEE_ID=100;

Resultado:

Resultado

Resultado

É possível até fazer tratamentos, como no exemplo abaixo, onde é criado uma trigger para tabela de notas, e gravando se é exclusão ou alteração:

--Trigger
CREATE OR REPLACE TRIGGER A_TRIG_NOTA
  BEFORE DELETE OR UPDATE 
  OF VALOR_NOTA ON A_NOTA
  FOR EACH ROW
DECLARE
    cTipo VARCHAR(6);
BEGIN

    --Update  
    IF updating THEN
      cTipo:='UPDATE';
    END IF;

    --Delete
    IF deleting THEN
      cTipo:='DELETE';
    END IF;

    --Inserindo dados
    insert into A_NOTA_LOG values ( A_SEQ_LOG.NEXTVAL,
                                    :old.RA,
                                    :old.COD_CURSO,
                                    :old.COD_DISC,
                                    :old.SEMESTRE_ANO,
                                    :old.SEQ_NOTA,
                                    :old.VALOR_NOTA,
                                    :new.VALOR_NOTA,
                                    SYSDATE,
                                    cTipo);
END;

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

2 Responses

  1. Rogério Alves Oliveira disse:

    Bom dia Atilio.

    Estou vendo o seu post sobre trigger e me surgiu uma necessidade em executar uma trigger e nessa trigger chamar um fonte em advpl. Sabe me informar se isso é possível e se você teria algum exemplo para me passar.

    Desde já, agradeço a atenção e parabéns pelo site.

    Rogério

    • Dan_Atilio disse:

      Boa noite Rogério, tudo bem?
      Rapaz, não sei dizer se é possível, pelo menos nunca precisei desenvolver algo assim.
      O que você pode fazer, é nessa triger, você chamar alguma function do oracle que gera um arquivo semaforo, e nesse caso, via AdvPL você poderia criar um job que ao ver esse semáforo, executa a função que você necessite.
      Abraços.

Deixe uma resposta

Terminal de Informação