Pular para o conteúdo principal
Documentos
Sintaxe básicaFunções JSONAcionadoresGerenciamento de tabelas e esquemasFunções de cadeia de caracteresFunções matemáticasFunções de dataBancos de dadosÍndices

Depuração do PostgreSQL

Os triggers do PostgreSQL são funções de retorno de chamada do banco de dados que são executadas automaticamente ou "acionadas" quando ocorre um evento especificado no banco de dados, como um `INSERT`, `UPDATE`, `DELETE` ou `TRUNCATE`. Eles são usados para manter a integridade dos dados, aplicar regras comerciais ou realizar registros e auditorias.

Uso

Os acionadores são usados quando você precisa automatizar tarefas em resposta a alterações nos dados de uma tabela. Eles são particularmente úteis para manter a consistência e implementar lógica comercial complexa no nível do banco de dados.

sql
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE | TRUNCATE }
ON table_name
[ FOR EACH ROW | FOR EACH STATEMENT ]
EXECUTE PROCEDURE function_name();

Nessa sintaxe, `CREATE TRIGGER` define um novo acionador chamado `trigger_name`, especificando quando ele deve ser acionado (`BEFORE`, `AFTER` ou `INSTEAD OF`), qual evento deve acioná-lo (`INSERT`, `UPDATE`, `DELETE` ou `TRUNCATE`) e a tabela à qual ele se aplica (`ON table_name`). O `EXECUTE PROCEDURE` chama a função que contém a lógica de acionamento.

Exemplos

1. Gatilho básico na inserção

sql
CREATE OR REPLACE FUNCTION log_insert()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO log_table(action, timestamp) VALUES ('INSERT', NOW());
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER insert_trigger
AFTER INSERT ON main_table
FOR EACH ROW
EXECUTE PROCEDURE log_insert();

Este exemplo cria um acionador que registra uma entrada na `log_table` toda vez que uma nova linha é inserida na `main_table`.

2. Acionador para aplicar a regra de negócios

sql
CREATE OR REPLACE FUNCTION check_salary()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.salary < 1000 THEN
    RAISE EXCEPTION 'Salary cannot be less than 1000';
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER salary_check
BEFORE INSERT OR UPDATE ON employees
FOR EACH ROW
EXECUTE PROCEDURE check_salary();

Aqui, um acionador garante que o salário de qualquer funcionário não seja definido abaixo de 1.000, seja na inserção ou na atualização.

3. Acionador para registro de auditoria

sql
CREATE OR REPLACE FUNCTION audit_changes()
RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'UPDATE' THEN
    INSERT INTO audit_log(table_name, operation, old_data, new_data, changed_at)
    VALUES (TG_TABLE_NAME, TG_OP, ROW(OLD.*), ROW(NEW.*), NOW());
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER audit_trigger
AFTER UPDATE ON any_table
FOR EACH ROW
EXECUTE PROCEDURE audit_changes();

Este exemplo captura as alterações em `any_table` registrando os dados da linha antiga e da nova em uma tabela `audit_log` após cada atualização.

Gerenciamento de acionadores

Para desativar um acionador:

sql
ALTER TABLE table_name DISABLE TRIGGER trigger_name;

Para ativar um acionador:

sql
ALTER TABLE table_name ENABLE TRIGGER trigger_name;

Para excluir um acionador:

sql
DROP TRIGGER trigger_name ON table_name;

Dicas e práticas recomendadas

  • Mantenha os acionadores simples e eficientes. A lógica complexa pode tornar as operações do banco de dados mais lentas. Tenha cuidado com as implicações de desempenho, especialmente em ambientes altamente transacionais.
  • Use acionadores para restrições críticas. Garanta que as regras comerciais essenciais sejam aplicadas no nível do banco de dados.
  • Limite os efeitos colaterais. Os acionadores devem evitar alterar o estado do banco de dados de forma inesperada.
  • Acionadores de documentos. Mantenha uma documentação clara de cada acionador para ajudar os futuros desenvolvedores a entender sua finalidade.
  • Faça um teste completo. Garantir que os acionadores funcionem conforme o esperado, testando com vários cenários e casos extremos.
  • Tenha em mente a ordem de execução. Entenda a ordem de execução quando vários acionadores são definidos para o mesmo evento em uma tabela.
  • Lidar com chamadas recursivas. Esteja ciente das possíveis chamadas de acionamento recursivas e implemente proteções quando necessário.