CodeGym /Cursos /SQL SELF /Fundamentos da sintaxe de triggers: CREATE TRIGGER, WHEN,...

Fundamentos da sintaxe de triggers: CREATE TRIGGER, WHEN, EXECUTE FUNCTION

SQL SELF
Nível 57 , Lição 2
Disponível

Pra criar um trigger no PostgreSQL, você precisa definir os seguintes componentes:

  • Nome do trigger.
  • Tipo do evento (INSERT, UPDATE, DELETE).
  • Momento de execução (BEFORE ou AFTER).
  • Tabela à qual ele está ligado.
  • Função que vai ser executada (em PL/pgSQL ou outra linguagem).

Aqui está a estrutura geral do comando:

CREATE TRIGGER nome_do_trigger
[BEFORE | AFTER] {INSERT | UPDATE | DELETE}
ON nome_da_tabela
[FOR EACH ROW | FOR EACH STATEMENT]
WHEN (condição)
EXECUTE FUNCTION nome_da_funcao();

Exemplo de trigger simples

Bora criar uma tabela básica students e adicionar um trigger que dispara depois de inserir um novo registro.

Primeiro, vamos criar a tabela students

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    last_modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

O que tá rolando aqui? A gente criou uma tabela com os campos id, name e last_modified. O campo last_modified vai guardar a data e hora da última alteração do registro.

Triggers sempre estão ligados a funções. Primeiro, vamos criar uma função simples que vai atualizar o campo last_modified toda vez que um registro for adicionado:

CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
    -- Definindo a data e hora atual no campo last_modified
    NEW.last_modified := CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Que bruxaria é essa?

  1. NEW — variável especial que guarda os novos valores da linha (pra eventos INSERT ou UPDATE).
  2. CURRENT_TIMESTAMP — função que retorna a data e hora atual.
  3. RETURN NEW — retorna a linha modificada pra ser salva depois.

Agora vamos criar o trigger em si:

CREATE TRIGGER set_last_modified
AFTER INSERT
ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();

Decifrando:

  • AFTER INSERT: o trigger dispara depois de inserir uma nova linha.
  • ON students: o trigger é aplicado na tabela students.
  • FOR EACH ROW: o trigger roda pra cada linha nova.
  • EXECUTE FUNCTION: diz qual função vai ser chamada.

Testando o trigger

Bora ver como nosso trigger funciona:

INSERT INTO students (name) VALUES ('Alice');
SELECT * FROM students;

Você vai ver algo assim:

id name last_modified
1 Alice 2023-10-15 14:23:45

O trigger atualizou automaticamente o campo last_modified. Mágica? Não, só PostgreSQL mesmo.

Usando condições com WHEN

Às vezes, você não quer que o trigger rode sempre, só em certas situações. Pra isso serve a palavra-chave WHEN.

Vamos ver um exemplo onde o trigger só roda pra certos valores.

Imagina que a gente quer que o trigger só dispare pra estudantes com o nome "Alice". Bora mudar nosso trigger:

CREATE OR REPLACE FUNCTION update_last_modified_condition()
RETURNS TRIGGER AS $$
BEGIN
    NEW.last_modified := CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER set_last_modified_condition
AFTER INSERT
ON students
FOR EACH ROW
WHEN (NEW.name = 'Alice')
EXECUTE FUNCTION update_last_modified_condition();

Agora o trigger só vai atualizar o campo last_modified pra estudantes com o nome "Alice".

Vamos testar:

INSERT INTO students (name) VALUES ('Alice');
INSERT INTO students (name) VALUES ('Bob');
SELECT * FROM students;

Resultado:

id name last_modified
1 Alice 2023-10-15 14:30:00
2 Bob (NULL)

Repara só: pro estudante "Bob" o campo last_modified ficou vazio, porque o trigger não rodou.

Ligando o trigger com a função: EXECUTE FUNCTION

Função é o coração de qualquer trigger. Trigger não existe sem uma função que define sua lógica. No PostgreSQL, você pode escrever funções em PL/pgSQL ou outras linguagens suportadas, tipo Python ou C.

Bora ver um exemplo usando função em PL/pgSQL.

Vamos criar uma função que registra mudanças numa tabela separada chamada audit_log.

Primeiro, criamos a tabela audit_log

CREATE TABLE audit_log (
    id SERIAL PRIMARY KEY,
    operation TEXT NOT NULL,
    student_id INTEGER NOT NULL,
    log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Agora – a função:

CREATE OR REPLACE FUNCTION log_insert()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log (operation, student_id)
    VALUES ('INSERT', NEW.id);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Agora vamos criar o trigger:

CREATE TRIGGER log_student_insert
AFTER INSERT
ON students
FOR EACH ROW
EXECUTE FUNCTION log_insert();

E testar:

INSERT INTO students (name) VALUES ('Charlie');
SELECT * FROM audit_log;

Você vai ver algo assim:

id operation student_id log_time
1 INSERT 3 2023-10-15 14:35:00

O trigger registrou automaticamente o log do novo registro.

Erros e particularidades ao trabalhar com triggers

Erro: falta de função. Se você tentar criar um trigger sem função, o PostgreSQL vai dar erro. Sempre crie a função antes do trigger.

Problemas de performance. Muitos triggers ou funções pesadas podem deixar o banco de dados lento. Use com moderação.

Recursão. Se o trigger faz alterações na mesma tabela onde ele dispara, pode rolar um loop infinito. Use condições WHEN pra evitar isso.

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