Casos de uso do PostgreSQL
Os gatilhos no PostgreSQL são funções de retorno de chamada do banco de dados que são executadas automaticamente quando ocorre um evento específico do banco de dados, como uma operação `INSERT`, `UPDATE` ou `DELETE`. Eles são usados para aplicar regras comerciais, validar dados de entrada e manter a integridade dos dados.
Uso
Os acionadores automatizam tarefas e aplicam regras no nível do banco de dados, garantindo que operações específicas ocorram em resposta a alterações nos dados. Eles consistem em um evento de acionamento, tempo e a função associada a ser executada.
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE }
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
Nessa sintaxe, `CREATE TRIGGER` define um novo acionador, especificando quando ele deve ser acionado (`ANTES`, `DEPOIS` ou `ENTRE` de um evento) e a função que deve ser executada. Os gatilhos `BEFORE` são normalmente usados para modificar dados antes de serem gravados no banco de dados, os gatilhos `AFTER` são usados para ações que devem ocorrer depois que os dados são confirmados e os gatilhos `INSTEAD OF` são frequentemente usados em visualizações para realizar as modificações necessárias nas tabelas subjacentes.
FOR EACH ROW
indica que a função de acionamento será executada uma vez para cada linha afetada pelo evento de acionamento. Por outro lado, o siteFOR EACH STATEMENT
pode ser usado para executar a função de acionamento uma vez por instrução SQL, independentemente do número de linhas afetadas.NEW
eOLD
são variáveis de registro especiais nos acionadores:NEW
contém os dados da nova linha para as operaçõesINSERT
ouUPDATE
eOLD
contém os dados da linha existente para as operaçõesUPDATE
ouDELETE
.
Exemplos
1. Gatilho de inserção básico
CREATE FUNCTION log_insert() RETURNS TRIGGER AS $$
BEGIN
-- Log every insert operation into log_table
INSERT INTO log_table(action, timestamp) VALUES ('Insert', now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER before_insert
BEFORE INSERT ON main_table
FOR EACH ROW
EXECUTE FUNCTION log_insert();
Este exemplo cria um acionador que registra cada operação de inserção na `tabela_principal` em uma `tabela_log`.
2. Atualizar gatilho com condição
CREATE FUNCTION update_timestamp() RETURNS TRIGGER AS $$
BEGIN
-- Update the updated_at timestamp field when a row is modified
NEW.updated_at := now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_time
BEFORE UPDATE ON main_table
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE FUNCTION update_timestamp();
Esse acionador atualiza o campo de registro de data e hora `updated_at` na `main_table` sempre que uma linha é modificada.
3. Acionador complexo para auditoria
CREATE FUNCTION audit_changes() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
-- Log DELETE operations into audit_log
INSERT INTO audit_log(action, old_data, timestamp) VALUES ('DELETE', OLD, now());
ELSIF (TG_OP = 'UPDATE') THEN
-- Log UPDATE operations with both old and new data
INSERT INTO audit_log(action, old_data, new_data, timestamp) VALUES ('UPDATE', OLD, NEW, now());
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON main_table
FOR EACH ROW
EXECUTE FUNCTION audit_changes();
Esse acionador registra as alterações feitas na `main_table` em um `audit_log`, capturando os dados antigos e novos para as operações `UPDATE`.
Dicas e práticas recomendadas
- Otimize o desempenho. Os acionadores podem aumentar a sobrecarga das operações do banco de dados, portanto, certifique-se de que sejam eficientes.
- Use os gatilhos com moderação. Evite o uso excessivo de acionadores para evitar complexidade e possíveis problemas de desempenho.
- Garanta a atomicidade. Certifique-se de que as funções de acionamento sejam atômicas e tratem as exceções para manter a integridade dos dados.
- Faça um teste completo. Teste rigorosamente os acionadores em um ambiente de desenvolvimento antes de implantá-los na produção para evitar efeitos colaterais indesejados.
- Considere alternativas. Avalie se os procedimentos armazenados ou a lógica do aplicativo podem ser mais adequados para determinadas operações, a fim de garantir clareza e facilidade de manutenção.