Triggers no MySQL: Guia Completo

O que é um Trigger?

Definição: Os triggers do MySQL, assim como os procedimentos armazenados, são programas embutidos no MySQL que funcionam como ferramentas poderosas para gerenciamento de dados. Eles são ativados e executados em resposta a operações específicas em tabelas, como INSERT, DELETE ou UPDATE. Por exemplo, quando uma operação é realizada na tabela de alunos, o trigger correspondente é acionado e executado.

Função: Os triggers estão intimamente relacionados às tabelas de dados e são principalmente usados para proteger os dados nas tabelas. Quando várias tabelas têm relações entre si, os triggers ajudam a manter a consistência dos dados, registros de log e validações de dados entre diferentes tabelas.

Vantagens e Desvantagens dos Triggers

Vantagens dos triggers:

  • A execução de triggers é automática, ocorrendo imediatamente após a modificação dos dados relacionados ao trigger.
  • Os triggers podem implementar verificações e operações mais complexas do que as restrições FOREIGN KEY e CHECK.
  • Os triggers permitem alterações em cascata nos dados das tabelas, garantindo em certa medida a integridade dos dados.

Desvantagens dos triggers:

  • Quando ocorrem problemas na lógica de negócio implementada com triggers, é difícil localizar a causa, especialmente quando vários triggers estão envolvidos, o que complica a manutenção posterior.
  • O uso excessivo de triggers pode desorganizar a estrutura do código, aumentando a complexidade do programa.
  • Quando grandes volumes de dados precisam ser modificados, a eficiência de execução dos triggers pode ser muito baixa.

Tipos de Triggers

Na prática, o MySQL suporta três tipos de triggers: INSERT, UPDATE e DELETE. São usados os aliases OLD e NEW para referenciar o conteúdo dos registros que estão sendo alterados, semelhante a outros bancos de dados. Atualmente, os triggers suportam apenas gatilho de nível de linha, não de nível de instrução.

Tipo de Trigger Uso de OLD e NEW
INSERT NEW representa os dados que serão ou já foram inseridos
UPDATE OLD representa os dados antes da modificação, NEW representa os dados após a modificação
DELETE OLD representa os dados que serão ou já foram excluídos

3.1 Trigger INSERT

Trigger que responde antes ou após a execução de uma instrução INSERT. Ao usar um trigger INSERT, considere os seguintes pontos:

  1. No código do trigger INSERT, pode-se referenciar uma tabela virtual chamada NEW (não diferencia maiúsculas de minúsculas) para acessar a linha sendo inserida.
  2. No trigger BEFORE INSERT, os valores em NEW podem ser atualizados, permitindo alterar os valores que serão inseridos (desde que as permissões correspondentes sejam concedidas).
  3. Para colunas AUTO_INCREMENT, NEW contém 0 antes da execução do INSERT e o novo valor gerado automaticamente após a execução.

3.2 Trigger UPDATE

Trigger que responde antes ou após a execução de uma instrução UPDATE. Ao usar um trigger UPDATE, considere os seguintes pontos:

  1. No código do trigger UPDATE, pode-se referenciar uma tabela virtual chamada NEW para acessar os valores atualizados.
  2. No código do trigger UPDATE, pode-se referenciar uma tabela virtual chamada OLD para acessar os valores antes da execução do UPDATE.
  3. No trigger BEFORE UPDATE, os valores em NEW podem ser atualizados, permitindo alterar os valores que serão usados na instrução UPDATE (desde que as permissões correspondentes sejam concedidas).
  4. Os valores em OLD são apenas de leitura e não podem ser atualizados.

Observação: Quando um trigger é projetado para realizar operações de atualização na própria tabela, apenas o tipo BEFORE é permitido; o tipo AFTER não é permitido.

3.3 Trigger DELETE

Trigger que responde antes ou após a execução de uma instrução DELETE. Ao usar um trigger DELETE, considere os seguintes pontos:

  1. No código do trigger DELETE, pode-se referenciar uma tabela virtual chamada OLD para acessar a linha sendo excluída.
  2. Os valores em OLD são apenas de leitura e não podem ser atualizados.

No geral, durante o uso de triggers, o MySQL processa os erros da seguinte forma:

  1. Para tabelas transacionais, se um trigger falhar e consequentemente toda a instrução falhar, todas as alterações realizadas pela instrução serão revertidas; para tabelas não transacionais, tal reversão não pode ser executada, e qualquer alteração feita antes da falha permanece válida.
  2. Se um trigger BEFORE falhar, o MySQL não executará a operação na linha correspondente.
  3. Se ocorrer um erro durante a execução de um trigger BEFORE ou AFTER, toda a instrução que chamou o trigger falhará.
  4. Apenas quando o trigger BEFORE e a operação na linha forem executados com sucesso, o MySQL executará o trigger AFTER.

Sintaxe Relacionada a Triggers

4.1 Criando um Trigger

No MySQL 5.7, pode-se usar a instrução CREATE TRIGGER para criar um trigger, com o seguinte formato de sintaxe:

CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON table_name FOR EACH ROW
trigger_body
  • Nome do trigger: O nome do trigger, que deve ser único no banco de dados atual. Para criar em um banco de dados específico, o nome deve ser prefixado com o nome do banco.
  • INSERT | UPDATE | DELETE: O evento que ativa o trigger, especificando o tipo de instrução que o aciona.
  • BEFORE | AFTER: O momento em que o trigger é ativado, indicando se o trigger é acionado antes ou depois da instrução que o ativa. Use BEFORE para validar novos dados; use AFTER para fazer alterações após a execução da instrução.
  • Nome da tabela: A tabela associada ao trigger, que deve ser uma tabela permanente. O mesmo trigger não pode ser associado a duas tabelas diferentes. Uma tabela não pode ter dois triggers com o mesmo momento e evento.
  • Corpo do trigger: O corpo da ação do trigger, contendo as instruções MySQL a serem executadas quando o trigger for ativado. Para executar múltiplas instruções, use a estrutura de instrução composta BEGIN...END.
  • FOR EACH ROW: Indica um gatilho de nível de linha, onde a ação do trigger é ativada para cada linha afetada pelo evento de gatilho.

Exemplo 1: Trigger de inserção

DELIMITER //
CREATE TRIGGER registro_usuario_insercao
AFTER INSERT INTO funcionarios
FOR EACH ROW
BEGIN
    INSERT INTO auditoria_acoes(id_acao, tipo_acao, data_acao, id_usuario, detalhes_acao) 
    VALUES (NULL, 'inclusao', NOW(), NEW.id_funcionario, CONCAT('Dados inseridos: ID=', NEW.id_funcionario, ', Nome=', NEW.nome, ', Cargo=', NEW.cargo));
END //
DELIMITER ;

Exemplo 2: Triggger de atualização

DELIMITER //
CREATE TRIGGER registro_usuario_atualizacao
AFTER UPDATE INTO funcionarios
FOR EACH ROW
BEGIN
    INSERT INTO auditoria_acoes(id_acao, tipo_acao, data_acao, id_usuario, detalhes_acao) 
    VALUES (NULL, 'atualizacao', NOW(), NEW.id_funcionario, 
    CONCAT('Antes: ID=', OLD.id_funcionario, ', Nome=', OLD.nome, ', Salário=', OLD.salario, 
           ' | Depois: ID=', NEW.id_funcionario, ', Nome=', NEW.nome, ', Salário=', NEW.salario));
END //
DELIMITER ;

Exemplo 3: Trigger de exclusão

DELIMITER //
CREATE TRIGGER registro_usuario_exclusao
AFTER DELETE FROM funcionarios
FOR EACH ROW
BEGIN
    INSERT INTO auditoria_acoes(id_acao, tipo_acao, data_acao, id_usuario, detalhes_acao) 
    VALUES (NULL, 'exclusao', NOW(), OLD.id_funcionario, 
    CONCAT('Registro excluído: ID=', OLD.id_funcionario, ', Nome=', OLD.nome, ', Departamento=', OLD.departamento));
END //
DELIMITER ;

4.2 Visualizando Triggers

No MySQL, pode-se usar a instrução SHOW TRIGGERS para ver informações básicas sobre os triggers:

SHOW TRIGGERS;

Todas as informações dos triggers estão na tabela triggers do banco de dados information_schema. Pode-se usar uma consulta SELECT para ver os detalhes:

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

Para ver todos os triggers:

SELECT * FROM information_schema.triggers;

4.3 Excluindo Triggers

Use a instrução DROP TRIGGER para excluir um trigger definido no MySQL:

DROP TRIGGER [IF EXISTS] [nome_do_banco] nome_do_trigger

Tags: MySQL triggers banco de dados SQL procedimentos armazenados

Publicado em 6-3 07:38 por Thomas