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>]
{DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>]
[OR DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>]…}
ON <tabela>
[REFERENCING {OLD [AS] <nome> | NEW [AS] <nome>
ON <tabela>
[REFERENCING {OLD [AS] <nome> | NEW [AS] <nome>
[OLD [AS] <nome> | NEW [AS] <nome>]}
FOR EACH ROW [WHEN (<condição>)]] <bloco PL/SQL/>
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
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;
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