Acionadores em nível de declaração do PostgreSQL
Os gatilhos no PostgreSQL são procedimentos especiais que são executados ou disparados automaticamente quando certos eventos ocorrem em uma tabela do banco de dados. Os acionadores em nível de instrução são executados uma vez por instrução SQL, independentemente do número de linhas afetadas pela instrução.
Uso
Os acionadores em nível de declaração são usados para aplicar regras de negócios, validar entradas ou manter registros de auditoria quando uma declaração afeta qualquer número de linhas. Eles são definidos para que você atue antes ou depois das operações `INSERT`, `UPDATE` ou `DELETE` em uma tabela.
sql
CREATE TRIGGER trigger_name
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON table_name
FOR EACH STATEMENT
EXECUTE PROCEDURE function_name();
Nessa sintaxe, `FOR EACH STATEMENT` especifica que o acionador deve ser disparado uma vez por instrução e `EXECUTE PROCEDURE` define a função a ser chamada. Observe que os acionadores em nível de instrução não têm acesso aos valores de linha `OLD` e `NEW`, pois não são específicos de linha.
Exemplos
1. Acionador básico em nível de declaração
sql
-- This function logs an entry into audit_log whenever an INSERT, UPDATE, or DELETE operation is performed on the employees table.
CREATE FUNCTION log_total_changes() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log(event_type, event_time)
VALUES (TG_OP, now());
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_changes
AFTER INSERT OR UPDATE OR DELETE
ON employees
FOR EACH STATEMENT
EXECUTE PROCEDURE log_total_changes();
2. Acionador para operações de inserção
sql
-- This function logs every INSERT operation on the employees table into the insert_log table with the current timestamp.
CREATE FUNCTION log_inserts() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO insert_log(table_name, insert_time)
VALUES (TG_TABLE_NAME, now());
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_employee_inserts
AFTER INSERT
ON employees
FOR EACH STATEMENT
EXECUTE PROCEDURE log_inserts();
3. Execução de acionamento condicional
sql
-- This function conditionally calls a notification function only when a DELETE operation is performed on the orders table.
CREATE FUNCTION notify_admin() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
PERFORM notify_admin_function();
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER admin_notification
AFTER DELETE
ON orders
FOR EACH STATEMENT
EXECUTE PROCEDURE notify_admin();
Nesses exemplos, `TG_OP` se refere ao tipo de operação (`INSERT`, `UPDATE` ou `DELETE`) e `TG_TABLE_NAME` se refere ao nome da tabela na qual o acionador está definido.
Dicas e práticas recomendadas
- Limite a complexidade do acionador. Mantenha a lógica de acionamento simples para evitar efeitos colaterais indesejados e manter o desempenho.
- Use os gatilhos com moderação. O uso excessivo pode levar a desafios de manutenção e dificultar a depuração.
- Documentar claramente os acionadores. Sempre documente a finalidade e a função dos acionadores em seu banco de dados.
- Faça um teste completo. Certifique-se de que os acionadores sejam testados minuciosamente para validar seu comportamento em vários cenários.
- Considere o impacto no desempenho. Esteja ciente de que os acionadores podem afetar o desempenho, especialmente em ambientes com muitas transações.
- Considere o uso de acionadores em nível de linha para lógica específica de linha. Os acionadores em nível de declaração não são adequados para operações específicas de linha, portanto, use acionadores em nível de linha conforme necessário.
- Entenda as diferenças de acionamento. Os acionadores em nível de declaração são executados uma vez por declaração sem acesso específico à linha, enquanto os acionadores em nível de linha são executados para cada linha afetada e podem acessar os valores de linha `OLD` e `NEW`.