Trabalhando com Triggers no MySQL

Não ouço comentários a respeito do uso de Triggers e Stored Procedures no banco de dados MySQL. Talvez por que, quem conheça e utilize estas ferramentas, prefira trabalhar com outros bancos mais robustos como Oracle, SQL Server e há espaço até para o PostgreSQL.

Esses dias, enquanto migrava uma aplicação que uso no trabalho do framework Code Igniter para o Kohana, percebi que poderia poupar código se fizesse a implementação de algumas atividades direto no banco, com o uso de Triggers, que estão disponíveis no MySQL 5.

Minha aplicação possui a entidade Tarefa, com 4 campos de data descritos, de forma que eu consigo controlar quando eu deveria ter iniciado a atividade, e comparar com quando, realmente, isso foi realizado. Os campos são: data prevista de início; data de início realizada; data prevista de término; e data de término realizada.

O problema que eu tinha é que muitas vezes eu precisava replanejar as datas previstas, por um motivo qualquer, como um atraso em uma atividade anterior, que era de responsabilidade do cliente. Então eu simplesmente entrava no sistema e alterava as datas previstas, mas precisava guardar um histórico, armazenando as datas anteriores e o motivo deste replanejamento.

Para resolver isto via código na aplicação, teria que implementar um método “after_save” em tarefas, verificar se houve replanejamento das datas, carregar um objeto entidade Replanejamento, preenche-lo com os dados e salvá-lo. A outra opção foi criar esta trigger no banco de dados:

CREATE TRIGGER log_replanejamento AFTER UPDATE ON tarefas
  FOR EACH ROW
    BEGIN
      IF OLD.dt_inicio_previsto <> NEW.dt_inicio_previsto OR OLD.dt_fim_previsto <> NEW.dt_fim_previsto THEN
        INSERT INTO replanejamentos SET
          tarefa_id = OLD.id,
          dt_inicio_previsto = OLD.dt_inicio_previsto,
          dt_inicio_realizado = OLD.dt_inicio_realizado,
          dt_fim_previsto = OLD.dt_fim_previsto,
          dt_fim_realizado = OLD.dt_fim_realizado,
          dt_replanejamento = NOW(),
          observacao = OLD.observacao;
      END IF;
    END;

Pra quem não está acostumado com a sintaxe das Triggers, uma “tradução” do comando seria: Crie a trigger LOG_REPLANEJAMENTO após atualizações em TAREFAS. Para cada linha, se a data de inicio prevista for diferente da nova data de inicio prevista, OU se a data de fim prevista for diferente da nova data fim prevista, insira na tabela REPLANEJAMENTOS.

Está lá o meu histórico: simples, rápido e indolor. :)

Mais informações no próprio manual do MySQL.

Related Posts:

Read More