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 (
BEFOREouAFTER). - 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?
NEW— variável especial que guarda os novos valores da linha (pra eventosINSERTouUPDATE).CURRENT_TIMESTAMP— função que retorna a data e hora atual.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 tabelastudents.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.
GO TO FULL VERSION