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:
- 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. - No trigger BEFORE INSERT, os valores em
NEWpodem ser atualizados, permitindo alterar os valores que serão inseridos (desde que as permissões correspondentes sejam concedidas). - Para colunas AUTO_INCREMENT,
NEWconté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:
- No código do trigger UPDATE, pode-se referenciar uma tabela virtual chamada
NEWpara acessar os valores atualizados. - No código do trigger UPDATE, pode-se referenciar uma tabela virtual chamada
OLDpara acessar os valores antes da execução do UPDATE. - No trigger BEFORE UPDATE, os valores em
NEWpodem ser atualizados, permitindo alterar os valores que serão usados na instrução UPDATE (desde que as permissões correspondentes sejam concedidas). - Os valores em
OLDsã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:
- No código do trigger DELETE, pode-se referenciar uma tabela virtual chamada
OLDpara acessar a linha sendo excluída. - Os valores em
OLDsã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:
- 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.
- Se um trigger BEFORE falhar, o MySQL não executará a operação na linha correspondente.
- Se ocorrer um erro durante a execução de um trigger BEFORE ou AFTER, toda a instrução que chamou o trigger falhará.
- 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