CodeGym /Cursos /SQL SELF /Trigger para atualizar automaticamente o campo las...

Trigger para atualizar automaticamente o campo last_modified quando um registro é alterado

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

Imagina que você tá desenvolvendo um app pra gerenciar estudantes e cursos, e tem uma tabela students. Nessa tabela tem o campo last_modified, que precisa ser atualizado automaticamente toda vez que algum dado do registro muda (tipo quando você muda o nome do estudante ou a idade dele).

Ao invés de ficar atualizando o last_modified manualmente em cada query SQL, bora criar um trigger que faz isso pra gente.

Estrutura da tabela students

Pra começar, bora criar a tabela students que a gente vai usar no exemplo. Essa tabela tem as infos básicas dos estudantes:

CREATE TABLE students (
    student_id SERIAL PRIMARY KEY, -- Identificador único do estudante
    name VARCHAR(100) NOT NULL,   -- Nome do estudante
    age INT,                      -- Idade do estudante
    last_modified TIMESTAMP NOT NULL DEFAULT NOW() -- Hora da última alteração
);
  • O campo last_modified já vem preenchido com a hora atual (NOW()) quando o registro é criado.
  • Esse campo vai ser atualizado automaticamente quando os dados do estudante mudarem.

Vamos colocar alguns dados de teste na tabela:

INSERT INTO students (name, age)
VALUES 
    ('Otto Lin', 20),
    ('Maria Chi', 22),
    ('Alex Song', 19);

Agora os dados na tabela ficam assim:

student_id name age last_modified
1 Otto Lin 20 2023-10-15 12:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Criando a função pra atualizar o last_modified

A função em PL/pgSQL vai ser usada pelo trigger pra atualizar o valor do campo last_modified. Ela vai ser chamada automaticamente antes de alterar o registro.

Bora criar a função update_last_modified:

CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
    -- Atualiza o campo last_modified pra hora atual
    NEW.last_modified := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
  • NEW — é uma variável especial que tem os dados novos do registro (depois da alteração).
  • A gente coloca em NEW.last_modified o valor de NOW() (data e hora atual).
  • A função retorna a variável NEW atualizada, que é o que o trigger precisa pra funcionar direito.

Criando o trigger

Agora bora criar o trigger que vai chamar automaticamente a função update_last_modified toda vez que um registro da tabela students for atualizado.

CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();

O que tá rolando aqui:

  • BEFORE UPDATE diz que o trigger roda antes da operação de update.
  • FOR EACH ROW quer dizer que o trigger roda pra cada linha alterada.
  • EXECUTE FUNCTION update_last_modified() manda chamar a função update_last_modified.

Testando o trigger

Agora bora ver como o trigger funciona. Vamos selecionar os dados atuais da tabela students:

SELECT * FROM students;

Resultado:

student_id name age last_modified
1 Otto Lin 20 2023-10-15 12:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Agora vamos atualizar a idade do estudante com student_id = 1:

UPDATE students
SET age = 21
WHERE student_id = 1;

Vamos selecionar de novo os dados da tabela:

SELECT * FROM students;

Resultado esperado:

student_id name age last_modified
1 Otto Lin 21 2023-10-15 14:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Repara: o campo last_modified do registro com student_id = 1 foi atualizado pra hora atual, enquanto os outros ficaram iguais.

Expandindo a lógica do trigger

Agora, imagina que você quer que o campo last_modified só seja atualizado se mudar certos campos. Tipo, se mudar só o nome ou a idade do estudante, o trigger roda, mas se mudar outra coisa, não.

Pra isso, dá pra colocar uma condição com o operador WHEN na definição do trigger.

Bora criar um novo trigger com condição:

DROP TRIGGER IF EXISTS set_last_modified ON students;

CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
WHEN (OLD.name IS DISTINCT FROM NEW.name OR OLD.age IS DISTINCT FROM NEW.age)
EXECUTE FUNCTION update_last_modified();

Aqui:

  • A condição WHEN checa se os valores antigos (OLD) são diferentes dos novos (NEW) nos campos name e age.
  • Se nenhum desses campos mudou, o trigger não roda.

Bora atualizar de novo os dados na tabela e testar essa lógica nova.

Dicas pra usar triggers

  1. Não exagere nos triggers. Eles são práticos, mas podem deixar a lógica do banco mais complicada e a depuração mais difícil.
  2. Sempre documenta o que o trigger faz e quando ele deve ser usado.
  3. Usa condições WHEN pra evitar que o trigger rode sem necessidade.
  4. Lembra que triggers podem afetar a performance do banco, principalmente se a tabela for grande.

Erros comuns ao trabalhar com triggers

Alteração errada dos dados. Tipo, esquecer de setar o valor pra NEW e retornar os dados originais sem mudar nada.

Condições erradas. Por exemplo, esquecer de colocar a condição WHEN e o trigger roda até quando não precisa mudar nada.

Recursão. Se o trigger chama uma função que chama o trigger de novo, pode acabar criando um loop infinito. O PostgreSQL tem proteção contra recursão, mas é melhor evitar esse tipo de situação.

Esse exemplo mostra como triggers podem facilitar a vida pra atualizar dados automaticamente. Em projetos reais, essa técnica é muito usada pra log de alterações, garantir integridade dos dados e automatizar tarefas chatas.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION