Acionadores em nível de linha do PostgreSQL
Os gatilhos no PostgreSQL são procedimentos que são executados automaticamente em resposta a determinados eventos em uma tabela ou visualização específica. Os acionadores em nível de linha são executados especificamente para cada linha afetada por um evento, como `INSERT`, `UPDATE` ou `DELETE`.
Uso
Os acionadores no nível da linha são utilizados para aplicar regras comerciais, validar dados ou manter o registro personalizado no nível da linha. Eles são definidos para executar ações específicas sempre que uma linha é modificada de uma maneira específica.
sql
CREATE TRIGGER trigger_name
AFTER | BEFORE INSERT | UPDATE | DELETE
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
Nessa sintaxe, `FOR EACH ROW` especifica que o acionador será disparado para cada linha afetada, e `EXECUTE FUNCTION` chama a função que contém a lógica a ser executada.
Exemplos
1. Gatilho de inserção básico
sql
CREATE OR REPLACE FUNCTION log_new_inserts()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation, timestamp)
VALUES (TG_TABLE_NAME, 'INSERT', now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_insert
AFTER INSERT ON employees
FOR EACH ROW
EXECUTE FUNCTION log_new_inserts();
Este exemplo cria um gatilho que registra cada nova operação `INSERT` na tabela `employees` em uma tabela `audit_log`.
2. Atualizar gatilho com condição
sql
CREATE OR REPLACE FUNCTION check_salary_update()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.salary < OLD.salary THEN
RAISE EXCEPTION 'Salary cannot be decreased!';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER salary_check
BEFORE UPDATE ON employees
FOR EACH ROW
EXECUTE FUNCTION check_salary_update();
Aqui, um acionador evita reduções salariais ao gerar uma exceção se o novo salário for menor que o antigo durante uma `UPDATE`.
3. Excluir acionador com registro
sql
CREATE OR REPLACE FUNCTION log_delete()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO delete_log (table_name, deleted_row_id, timestamp)
VALUES (TG_TABLE_NAME, OLD.id, now());
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_delete
AFTER DELETE ON orders
FOR EACH ROW
EXECUTE FUNCTION log_delete();
Este exemplo registra os detalhes das linhas excluídas da tabela `orders` em um `delete_log` para fins de auditoria. Ele pressupõe que `OLD.id` corresponde à chave primária ou a um identificador exclusivo da linha.
Dicas e práticas recomendadas
- Use os acionadores de forma criteriosa. O uso excessivo de acionadores pode levar a sistemas complexos e difíceis de depurar.
- Garanta a atomicidade. A função de acionamento deve ser atômica e idempotente para manter a integridade dos dados.
- Considere os impactos no desempenho. Os acionadores adicionam sobrecarga e são executados de forma síncrona com a operação de acionamento; certifique-se de que eles sejam otimizados para o desempenho, a fim de evitar a lentidão das operações do banco de dados.
- Teste os acionadores minuciosamente. Garanta a realização de testes abrangentes para validar se os acionadores se comportam corretamente em todos os cenários.
- Documentar a lógica de acionamento. Documente claramente a finalidade e a lógica de cada acionador para referência e manutenção futuras.
Informações adicionais
Variáveis especiais: Os triggers do PostgreSQL utilizam variáveis especiais como `TG_TABLE_NAME`, `NEW` e `OLD` para fornecer contexto. A variável `TG_TABLE_NAME` refere-se ao nome da tabela à qual o acionador está associado, a variável `NEW` contém os dados da nova linha para operações `INSERT` ou `UPDATE` e a variável `OLD` contém os dados da linha existente para operações `UPDATE` ou `DELETE`.