segunda-feira, 13 de junho de 2011

Criação de triggers (gatilhos) com PL/SQL

Um DATABASE TRIGGER é um programa PL/SQL armazenado em um banco ORACLE, associado com uma tabela específica. O ORACLE irá disparar a execução do DATABASE TRIGGER automaticamente quando uma determinada operação SQL afeta a tabela.

Deste forma, pode-se usar um DATABASE TRIGGER para:

- Logar modificações
- garantir críticas complexas
- Gerar o valor de colunas
- Implementar níveis de segurança mais complexos
- Manter tabelas duplicadas

Pode-se associar até 12 DATABASE TRIGGERS a cada tabela, um de cada tipo (BEFORE UPDATE <row>, BEFORE DELETE <row>, BEFORE INSERT <row>, BEFORE INSERT <comando>, BEFORE UPDATE <comando>, BEFORE DELETE <comando> e as mesmas sintaxes para AFTER). Um DATABASE TRIGGER é composto de 3 partes:

- evento
- constraint (opcional)
- ação

Quando o evento ocorre, o trigger é disparado e um bloco PL/SQL "anônimo" executa a ação.

Deve-se observar que os DATABASE TRIGGERS executam com os privilégios do OWNER e não do usuário corrente.

sintaxe:

CREATE [OR REPLACE] TRIGGER <nome trigger>
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>]
          [OR DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>]…}
ON <tabela>
[REFERENCING {OLD [AS] <nome> | NEW [AS] <nome> 
          [OLD [AS] <nome> | NEW [AS] <nome>]}
FOR EACH ROW [WHEN (<condição>)]] <bloco PL/SQL/>

Ex.:

CREATE TRIGGER checa_salario
          BEFORE UPDATE OF vl_sal, nr_git ON FUNC 
          FOR EACH ROW WHEN (NEW.nr_git < 56)
          DECLARE
                    salario_minimo NUMBER(5) := 0;
                    salario_maximo NUMBER(5) := 0;
                    faixa EXCEPTION;
                    negativo EXCEPTION;
                    excede EXCEPTION;
          BEGIN
                    SELECT MIN(vl_sal), MAX(vl_sal)
                    INTO salario_minimo, salario_maximo
                    FROM folha
                    WHERE nr_git = :new.nr_git;
                    IF (:NEW.vl_sal < salario_minimo OR
                    :NEW.vl_sal > salario_maximo)
                    THEN
                    RAISE faixa
                    ELSIF (:NEW.vl_sal < OLD.vl_sal)
                    THEN
                    RAISE negativo;
                    ELSIF (:New.vl_sal > 1.1 * :OLD.vl_sal)
                    THEN
                    RAISE excede;
                    END IF;
          EXCEPTION
          WHEN faixa THEN
                    RAISE_APPLICATION_ERROR(-20225, ‗Salário fora da faixa‘);
          WHEN negativo THEN
                    RAISE_APPLICATION_ERROR(-20230, ‗Incremento negativo‘);
          WHEN excede THEN
                    RAISE_APPLICATION_ERROR(-20235, ‗Incremento excede 10%‘);
          WHEN OTHERS THEN
                    RAISE_APPLICATION_ERROR(-20999, SQLERRM(SQLCODE));
          END;

0 comentários:

Postar um comentário