Use CREATE TRIGGER para definir um trigger e armazená-lo no banco de dados. Os triggers disparam automaticamente em eventos de INSERT, UPDATE ou DELETE. Assim, você aplica regras de negócio, audita alterações ou mantém dados derivados sincronizados sem código no nível da aplicação.
Pré-requisitos
Antes de começar, verifique se você tem o privilégio CREATE TRIGGER na tabela de destino.
Sintaxe
CREATE [ OR REPLACE ] TRIGGER name
{ BEFORE | AFTER | INSTEAD OF }
{INSERT | UPDATE | DELETE}
[ OR { INSERT | UPDATE | DELETE } ] [, ...]
ON table
[ REFERENCING { OLD AS old | NEW AS new } ...]
[ FOR EACH ROW ]
[ WHEN condition ]
[ DECLARE
[ PRAGMA AUTONOMOUS_TRANSACTION; ]
declaration; [, ...] ]
BEGIN
statement; [, ...]
[ EXCEPTION
{ WHEN exception [ OR exception ] [...] THEN
statement; [, ...] } [, ...]
]
END
Descrição
O comando CREATE TRIGGER define um novo trigger. O comando CREATE OR REPLACE TRIGGER cria um trigger ou substitui uma definição existente.
Ao criar um novo trigger, o nome não pode coincidir com nenhum trigger existente na mesma tabela. O sistema cria o novo trigger no mesmo schema da tabela onde o evento de disparo está definido. Para atualizar a definição de um trigger existente, use CREATE OR REPLACE TRIGGER.
Tempo e comportamento do trigger
O momento de execução determina quando o trigger dispara em relação à verificação de restrições e quais ações o corpo do trigger pode executar:
BEFORE: O trigger dispara antes da verificação das restrições e antes da tentativa da operação DML. O corpo do trigger pode modificar a linha inserida ou atualizada, ou cancelar toda a operação.AFTER: O disparo ocorre após a verificação das restrições e a conclusão da operação DML. Todas as alterações, inclusive as feitas por outros triggers, ficam visíveis para o corpo do trigger.INSTEAD OF: Válido apenas em views. O trigger dispara no lugar da operação DML. UseINSTEAD OFpara permitir que views não atualizáveis aceitem operações deINSERT,UPDATEeDELETE.
Triggers no nível de linha versus no nível de instrução
Nível de linha (
FOR EACH ROW): dispara uma vez para cada linha afetada. Um comandoDELETEque remove 10 linhas aciona o trigger 10 vezes.Nível de instrução (sem
FOR EACH ROW): dispara uma única vez por instrução SQL, independentemente da quantidade de linhas afetadas, inclusive zero.
Segurança
Ao criar um trigger com sintaxe compatível com Oracle, ele executa como uma função SECURITY DEFINER. Isso significa que a execução usa os privilégios do proprietário do trigger, e não do usuário que causou o disparo.
A cláusulaREFERENCINGnão é totalmente compatível com o Oracle Database. Os identificadores apósOLD ASeNEW ASdevem seroldenewou qualquer equivalente salvo inteiramente em letras minúsculas (por exemplo,REFERENCING OLD AS old,REFERENCING OLD AS OLDouREFERENCING OLD AS "old"). Identificadores diferentes deoldounewnão têm suporte.
Parâmetros
|
Parâmetro |
Descrição |
||
|
|
Nome do trigger a criar. |
||
|
|
AFTER |
INSTEAD OF` |
Momento de execução do trigger em relação ao evento de disparo. |
|
|
UPDATE |
DELETE` |
Evento DML que aciona o trigger. Combine vários eventos com |
|
|
Nome da tabela ou view onde ocorre o evento de disparo. |
||
|
|
Expressão booleana que controla a execução do trigger. O disparo ocorre apenas quando a |
||
|
|
NEW AS new } ...` |
Alias para os valores antigos e novos da linha. O alias após |
|
|
|
Define o trigger como nível de linha: o disparo ocorre uma vez para cada linha afetada pelo evento. Sem esta cláusula, o trigger opera no nível de instrução e dispara apenas uma vez por comando SQL. |
||
|
|
Configura o trigger como uma transação autônoma. Isso permite confirmar (commit) ou reverter (rollback) independentemente da transação que originou o disparo. |
||
|
|
Declaração de variável, tipo, |
||
|
|
Instrução da Structured Process Language (SPL). Um bloco |
||
|
|
Nome de uma condição de exceção a tratar, como |
Exemplos
Trigger BEFORE INSERT no nível de linha
Este trigger atribui um timestamp ao campo created_at antes da inserção de cada linha em orders.
CREATE OR REPLACE TRIGGER set_created_at
BEFORE INSERT ON orders
FOR EACH ROW
DECLARE
BEGIN
:NEW.created_at := SYSDATE;
END;
Trigger AFTER UPDATE no nível de linha com condição WHEN
O exemplo abaixo registra uma linha em salary_audit somente quando há alteração efetiva na coluna salary.
CREATE OR REPLACE TRIGGER log_salary_change
AFTER UPDATE ON employees
FOR EACH ROW
WHEN (OLD.salary != NEW.salary)
DECLARE
BEGIN
INSERT INTO salary_audit (emp_id, old_salary, new_salary, changed_at)
VALUES (:OLD.emp_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
Trigger AFTER DELETE no nível de instrução
Registra uma única entrada de auditoria sempre que uma instrução DELETE é executada em orders, independentemente do número de linhas excluídas.
CREATE OR REPLACE TRIGGER audit_order_delete
AFTER DELETE ON orders
DECLARE
BEGIN
INSERT INTO audit_log (action, action_time)
VALUES ('DELETE from orders', SYSDATE);
END;
Trigger INSTEAD OF em uma view
Intercepta instruções de INSERT na view active_employees e as redireciona para a tabela subjacente employees.
CREATE OR REPLACE TRIGGER insert_active_employee
INSTEAD OF INSERT ON active_employees
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO employees (emp_id, name, status)
VALUES (:NEW.emp_id, :NEW.name, 'ACTIVE');
END;