Implementação e Gerenciamento de Triggers no MySQL

O que são Triggers no MySQL?

Um trigger (ou gatilho) no MySQL é um bloco de código procedural armazenado no banco de dados que é executado automaticamente em resposta a eventos específicos em uma tabela. Semelhante a uma stored procedure, sua principle função é garantir a integridade dos dados. Eles são extremamente úteis para manter a consistência entre tabelas relacionadas, realizar auditorias de alterações (logs) e validar regras de negócio complexas antes que os dados sejam persistidos.

Vantagens e Desvantagens

Benefícios

  • Automação: São executados de forma transparente e imediata sempre que ocorre uma modificação na tabela associada.
  • Validação Avançada: Permitem a implementação de regras de integridade muito mais sofisticadas do que as oferecidas por constraints padrão como FOREIGN KEY ou CHECK.
  • Consistência: Facilitam a atualização em cascata e garantem que dados dependentes em múltiplas tabelas permaneçam sincronizados.

Limitações

  • Complexidade de Manutenção: A lógica de negócios embutida em triggres pode se tornar invisível para a aplicação, dificultando o rastreamento de bugs e o debugging, especialmente em arquiteturas com muitos gatilhos.
  • Acoplamento: O uso excessivo pode espalhar regras de negócio pelo banco de dados, tornando a estrutura do código difícil de compreender e gerenciar.
  • Impacto no Desempenho: Em operações de alto volume (bulk inserts/updates), a execução síncrona dos triggers pode introduzir uma sobrecarga significativa no servidor de banco de dados.

Classificação e Comportamento

O MySQL suporta triggers acionados por três operações DML (Data Manipulation Language): INSERT, UPDATE e DELETE. Além disso, eles podem ser configurados para disparar BEFORE (antes) ou AFTER (depois) da operação. Atualmente, o MySQL suporta apenas triggers em nível de linha (FOR EACH ROW).

Durante a execução, o MySQL disponibiliza duas tabelas virtuais (ou pseudo-registros) para acessar os dados em transição:

  • NEW: Contém os valores que estão sendo inseridos ou os novos valores de uma atualização.
  • OLD: Contém os valores originais antes de uma atualização ou exclusão.

Triggers de Inserção (INSERT)

Disparados ao adicionar novos registros. O objeto NEW é utilizado para acessar os dados de entrada. Em triggers BEFORE INSERT, é possível modificar os valores de NEW para alterar o que será efetivamente salvo. Para colunas auto-incrementáveis, o valor de NEW só estará disponível no estágio AFTER.

Triggers de Atualização (UPDATE)

Acionados quando registros existentes são modificados. Ambos os objetos OLD (dados anteriores) e NEW (novos dados) estão acessíveis. Triggers BEFORE UPDATE permitem interceptar e alterar os valores em NEW. O objeto OLD é estritamente somente leitura. Vale notar que um trigger não pode modificar a própria tabela que o acionou no estágio AFTER, para evitar loops infinitos (erro de mutating table).

Triggers de Exclusão (DELETE)

Executados ao remover dados. Apenas o objeto OLD está disponível, pois não há novos dados sendo gerados. Assim como no UPDATE, os valores em OLD são somente leitura.

Tratamento de Erros

Se um trigger BEFORE falhar, a operação DML correspondente é abortada. Se um trigger AFTER falhar, toda a transação é revertida (em tabelas transacionais como InnoDB). Um trigger AFTER só é executado se o trigger BEFORE e a operação DML principal forem bem-sucedidos.

Sintaxe e Gerenciamento

Criação de Triggers

A instrução CREATE TRIGGER é utilizada para definir um novo gatilho. O nome deve ser único dentro do esquema do banco de dados.

CREATE TRIGGER nome_do_trigger
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON nome_da_tabela
FOR EACH ROW
BEGIN
    -- Instruções SQL
END;

Exemplo Prático: Sistema de Auditoria de Produtos

Abaixo, demonstramos como registrar as alterações de uma tabela de products em uma tabela de auditoria chamada audit_logs.

1. Registrando Novas Inserções:

DELIMITER //

CREATE TRIGGER trg_audit_product_insert
AFTER INSERT ON products
FOR EACH ROW
BEGIN
    INSERT INTO audit_logs (log_action, log_timestamp, target_id, description) 
    VALUES (
        'INSERT', 
        CURRENT_TIMESTAMP, 
        NEW.id, 
        CONCAT('Produto criado: ', NEW.product_name, ' | Preço: ', NEW.price)
    );
END //

DELIMITER ;

2. Rastreando Atualizações:

DELIMITER //

CREATE TRIGGER trg_audit_product_update
AFTER UPDATE ON products
FOR EACH ROW
BEGIN
    IF OLD.price != NEW.price THEN
        INSERT INTO audit_logs (log_action, log_timestamp, target_id, description) 
        VALUES (
            'UPDATE', 
            CURRENT_TIMESTAMP, 
            NEW.id, 
            CONCAT('Alteração de preço - De: ', OLD.price, ' Para: ', NEW.price)
        );
    END IF;
END //

DELIMITER ;

3. Log de Exclusões:

DELIMITER //

CREATE TRIGGER trg_audit_product_delete
AFTER DELETE ON products
FOR EACH ROW
BEGIN
    INSERT INTO audit_logs (log_action, log_timestamp, target_id, description) 
    VALUES (
        'DELETE', 
        CURRENT_TIMESTAMP, 
        OLD.id, 
        CONCAT('Produto excluído: ', OLD.product_name)
    );
END //

DELIMITER ;

Consulta e Inspeção

Para listar os gatilhos existentes no banco de dados atual, utiliza-se o comando:

SHOW TRIGGERS;

Para uma inspeção mais detalhada, o dicionário de dados information_schema armazena metadados sobre todos os triggers:

SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg_audit_product_insert';

Remoção de Triggers

Quando um gatilho não é mais necessário, ele pode ser eliminado do banco de dados utilizando o comando DROP TRIGGER:

DROP TRIGGER IF EXISTS trg_audit_product_insert;

Tags: MySQL triggers SQL InnoDB DatabaseAdministration

Publicado em 6-3 23:22 por Thomas