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

Acionadores do PostgreSQL BEFORE

Os gatilhos no PostgreSQL são funções que são executadas automaticamente em resposta a eventos específicos em uma tabela, como INSERT, UPDATE ou DELETE. Um acionador `BEFORE` é disparado antes que o evento ocorra, permitindo que você modifique os dados ou imponha restrições antes que as alterações de dados sejam confirmadas.

Uso
Os acionadores `BEFORE` são usados para validar ou modificar dados antes de serem inseridos, atualizados ou excluídos em uma tabela. Eles são frequentemente empregados para aplicar regras comerciais, validar a integridade dos dados ou atualizar automaticamente os campos.

sql
CREATE TRIGGER trigger_name
BEFORE INSERT OR UPDATE OR DELETE
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();

Nessa sintaxe, a palavra-chave `BEFORE` especifica que o acionador deve ser ativado antes da ocorrência do(s) evento(s) especificado(s). Os acionadores `BEFORE` diferem dos acionadores `AFTER`, pois os acionadores `BEFORE` são executados antes do evento, permitindo a manipulação de dados antes que a transação seja finalizada.

Exemplos

1. Acionador básico BEFORE INSERT

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

CREATE TRIGGER check_salary_trigger
BEFORE INSERT
ON employees
FOR EACH ROW
EXECUTE FUNCTION check_positive_salary();

Este exemplo cria um acionador que verifica se o `salário` é positivo antes que uma nova linha seja inserida na tabela `funcionários`.

2. Acionamento do BEFORE UPDATE para registrar alterações

sql
CREATE OR REPLACE FUNCTION log_update()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO employees_audit(employee_id, old_salary, new_salary, changed_on)
  VALUES(OLD.id, OLD.salary, NEW.salary, CURRENT_TIMESTAMP);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER log_update_trigger
BEFORE UPDATE
ON employees
FOR EACH ROW
EXECUTE FUNCTION log_update();

Aqui, um gatilho registra as alterações no campo `salary` em uma tabela `employees_audit` antes que ocorra uma atualização.

3. Acionador BEFORE DELETE para ações em cascata

sql
CREATE OR REPLACE FUNCTION prevent_deletion()
RETURNS TRIGGER AS $$
BEGIN
  IF EXISTS (SELECT 1 FROM orders WHERE orders.employee_id = OLD.id) THEN
    RAISE EXCEPTION 'Employee cannot be deleted, related orders exist';
  END IF;
  RETURN OLD;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER prevent_deletion_trigger
BEFORE DELETE
ON employees
FOR EACH ROW
EXECUTE FUNCTION prevent_deletion();

Esse acionador impede que você exclua um funcionário se houver ordens relacionadas na tabela `orders`.

Dicas e práticas recomendadas

  • Use nomes de acionadores descritivos. Isso melhora a legibilidade e a manutenção, deixando claro o que cada acionador foi projetado para fazer.
  • Mantenha as funções de acionamento simples. A lógica complexa pode levar a problemas de desempenho e é mais difícil de depurar.
  • Faça um teste completo. Certifique-se de que os acionadores se comportem conforme o esperado em todos os cenários para evitar problemas de integridade de dados.
  • Acionadores de documentos. Documente claramente a finalidade e a lógica de cada acionador para referência futura e colaboração da equipe.
  • Considere o impacto no desempenho. Os acionadores podem afetar o desempenho; use-os criteriosamente, especialmente em tabelas grandes ou operações frequentes.
  • Entenda o comportamento da transação. Os acionadores `BEFORE` são executados dentro da transação que os acionou, e as alterações podem ser revertidas se a transação falhar.
  • Retorna a linha correta. Sempre retorne `NEW` ou `OLD` adequadamente para garantir que o acionador funcione corretamente.
  • Desativar temporariamente os acionadores. Você pode desativar os acionadores durante operações em massa ou tarefas de manutenção usando `ALTER TABLE nome_da_tabela DISABLE TRIGGER nome_do_acionador;` e reativá-los com `ALTER TABLE nome_da_tabela ENABLE TRIGGER nome_do_acionador;`.