CodeGym /Cursos /SQL SELF /Automatizando tarefas com triggers

Automatizando tarefas com triggers

SQL SELF
Nível 58, Lição 0
Disponível

Imagina a situação: você é admin de um banco de dados grandão. Do nada, alguém apaga uma informação importante da tabela e todo mundo grita: "Quem fez isso?!". Pra evitar esse tipo de perrengue, os bancos de dados permitem registrar mudanças e acompanhar o que rolou com os dados. Tudo isso rola com log e auditoria.

  • Log de mudanças permite guardar o histórico do que rolou: qual registro mudou, como e quando.
  • Auditoria de dados serve pra uma checagem mais profunda, incluindo não só as mudanças, mas também info sobre o usuário que fez a parada.

Agora que você já entendeu o "porquê", bora aprender o "como".

Criando uma tabela pra logs

Antes de configurar os triggers, a gente precisa de uma tabela pra guardar os logs das mudanças. Olha só esse exemplo:

-- Criando tabela pra logar mudanças
CREATE TABLE change_logs (
    log_id SERIAL PRIMARY KEY,       -- Identificador único do registro
    table_name TEXT NOT NULL,        -- Nome da tabela onde rolou a mudança
    operation TEXT NOT NULL,         -- Tipo de operação: INSERT, UPDATE, DELETE
    change_time TIMESTAMP DEFAULT NOW(), -- Momento da mudança
    old_data JSONB,                  -- Dados antes da mudança (pra UPDATE/DELETE)
    new_data JSONB                   -- Dados depois da mudança (pra INSERT/UPDATE)
);

O que tá rolando aqui?

  1. log_id — identificador único pra cada registro do log.
  2. table_name — a gente vai registrar qual tabela foi alterada.
  3. operation — tipo da operação: INSERT, UPDATE ou DELETE.
  4. change_time — marca o momento exato da mudança.
  5. old_data e new_data — dados antes e depois da mudança, em formato JSON.

Logando mudanças com trigger

Agora que temos a tabela de logs, bora criar um trigger pra uma das tabelas, tipo students. Ele vai registrar todas as mudanças: adicionar novos estudantes, atualizar ou deletar. Olha o que vamos fazer:

  1. Vamos escrever uma função em PL/pgSQL que adiciona registros na tabela de logs.
  2. Vamos criar um trigger na tabela students.

A função vai receber info sobre a operação (INSERT, UPDATE, DELETE), além dos dados que mudaram (OLD e NEW).

-- Função pra registrar mudanças na tabela de logs
CREATE OR REPLACE FUNCTION log_student_changes()
RETURNS TRIGGER AS $$
BEGIN
    -- Logando operação INSERT
    IF TG_OP = 'INSERT' THEN
        INSERT INTO change_logs (table_name, operation, new_data)
        VALUES ('students', 'INSERT', row_to_json(NEW));

    -- Logando operação DELETE
    ELSIF TG_OP = 'DELETE' THEN
        INSERT INTO change_logs (table_name, operation, old_data)
        VALUES ('students', 'DELETE', row_to_json(OLD));

    -- Logando operação UPDATE
    ELSIF TG_OP = 'UPDATE' THEN
        INSERT INTO change_logs (table_name, operation, old_data, new_data)
        VALUES ('students', 'UPDATE', row_to_json(OLD), row_to_json(NEW));
    END IF;

    RETURN NULL; -- Retorna NULL porque é um AFTER-trigger
END;
$$ LANGUAGE plpgsql;

Aqui:

  • TG_OP — variável especial que guarda a operação atual: INSERT, UPDATE, DELETE.
  • row_to_json(OLD) e row_to_json(NEW) — transformam os dados da linha pra JSON, pra facilitar o armazenamento.
  • RETURN NULL — como é um AFTER-trigger, não precisa retornar dados alterados.

Agora vamos ligar nossa função à tabela students.

-- Criando trigger pra logar mudanças
CREATE TRIGGER students_log_trigger
AFTER INSERT OR UPDATE OR DELETE ON students
FOR EACH ROW
EXECUTE FUNCTION log_student_changes();

O que tá rolando aqui?

  • AFTER INSERT OR UPDATE OR DELETE — o trigger dispara depois das operações na tabela students.
  • FOR EACH ROW — o trigger roda pra cada linha alterada.
  • EXECUTE FUNCTION log_student_changes() — chama nossa função de log.

Testando o trigger

Chegou a hora de testar nosso trigger.

  1. Inserindo um novo registro
INSERT INTO students (name, age, grade)
VALUES ('Otto Lin', 20, 'A');

Bora ver o que foi registrado na tabela de logs:

SELECT * FROM change_logs;

Exemplo de resultado:

log_id table_name operation change_time old_data new_data
1 students INSERT 2023-10-10 12:00:00 NULL {"name": "Otto Lin", "age": 20, ...}
  1. Atualizando um registro
UPDATE students
SET grade = 'B'
WHERE name = 'Otto Lin';

De novo, vamos checar a tabela de logs:

SELECT * FROM change_logs ORDER BY change_time DESC;

Resultado:

log_id table_name operation change_time old_data new_data
2 students UPDATE 2023-10-10 12:05:00 {"name": "Otto Lin", "age": ...} {"name": "Otto Lin", "age": ..., ...}
  1. Deletando um registro
DELETE FROM students
WHERE name = 'Otto Lin';

E mais uma vez, bora conferir o log:

log_id table_name operation change_time old_data new_data
3 students DELETE 2023-10-10 12:10:00 {"name": "Otto Lin", "age": ...} NULL

Exemplos de uso na vida real

  1. Log de operações em tabelas críticas: por exemplo, uma tabela de contas bancárias precisa registrar todas as mudanças pra evitar fraude.
  2. Auditoria do sistema: você pode guardar registros pra cumprir normas ou analisar o que os usuários estão fazendo.
  3. Garantir recuperação de dados: se alguém apagar dados sem querer, dá pra recuperar usando a tabela de logs.

Peculiaridades e pegadinhas

Quando for implementar log com triggers, é importante pensar na performance. Se o trigger dispara toda hora, pode sobrecarregar o banco. Então:

  • Use log só nas tabelas realmente importantes.
  • Se o volume de logs ficar gigante, pense em estratégias de arquivamento.

Triggers são tipo corda de guitarra bem afinada: exigem ajuste fino, mas deixam tudo rodando bonito, automatizando tarefas chatas e garantindo controle sobre os dados.

2
Tarefa
SQL SELF, nível 58, lição 0
Bloqueado
Implementação de trigger com logging
Implementação de trigger com logging
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION