PostgreSQL 触发器

目录

入门

简介

PostgreSQL 的 触发器 Trigger 是一类特殊的数据库对象,在表的 INSERT、UPDATE 或 DELETE 事件发生时,自动执行预定义的函数(触发器函数)。它常用于 数据完整性约束、审计日志、自动计算、复杂的业务逻辑处理等场景

触发器的构成

一个完整的触发器由两个部分组成:

触发器函数(Trigger Function):触发器执行的具体逻辑,必须返回 TRIGGER 类型

触发器(Trigger):绑定到表的某个事件上,调用触发器函数

触发器的类型

按照触发时间分类

  • BEFORE 触发器(在事件发生前执行)
  • AFTER 触发器(在事件发生后执行)
  • INSTEAD OF 触发器(替代事件执行,仅适用于视图)

按照触发事件分类

  • INSERT 触发器(在插入新数据时触发)
  • UPDATE 触发器(在数据更新时触发)
  • DELETE 触发器(在数据删除时触发)
  • TRUNCATE 触发器(在 TRUNCATE 操作时触发)

按照触发级别分类

  • 行级触发器(FOR EACH ROW):对受影响的每一行数据触发一次
  • 语句级触发器(FOR EACH STATEMENT):对整个 SQL 语句仅触发一次

创建触发器

简介

PostgreSQL 触发器的创建需要两步:

  1. 编写触发器函数(必须返回 TRIGGER 类型)
  2. 创建触发器 并绑定到表

假设我们有一个 users 表,我们希望在有新用户插入时,自动记录日志到 user_logs 表中

示例 1:审计日志

Step 1: 创建审计日志表

sql 复制代码
CREATE TABLE user_logs (
    log_id SERIAL PRIMARY KEY,
    user_id UUID,
    action TEXT,
    log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Step 2: 编写触发器函数

sql 复制代码
CREATE OR REPLACE FUNCTION log_user_insert() RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO user_logs (user_id, action)
    VALUES (NEW.id, 'User created');
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Step 3: 创建触发器

sql 复制代码
CREATE TRIGGER user_insert_trigger
AFTER INSERT ON users
FOR EACH ROW
EXECUTE FUNCTION log_user_insert();

示例 2:自动更新修改时间

假设 users 表中有一个 updated_at 字段,我们希望在用户数据更新时,自动更新 updated_at 时间戳。

Step 1: 在 users 表添加 updated_at 字段

sql 复制代码
ALTER TABLE users ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

Step 2: 创建触发器函数

sql 复制代码
CREATE OR REPLACE FUNCTION update_timestamp() RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Step 3: 创建触发器

sql 复制代码
CREATE TRIGGER update_users_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();

示例 3:防止 DELETE

有时我们不希望某些重要数据被删除,可以通过 BEFORE DELETE** 触发器阻止删除**。

Step 1: 创建触发器函数

sql 复制代码
CREATE OR REPLACE FUNCTION prevent_delete() RETURNS TRIGGER AS $$
BEGIN
    RAISE EXCEPTION '不允许删除数据!';
END;
$$ LANGUAGE plpgsql;

Step 2: 绑定到 users

sql 复制代码
CREATE TRIGGER prevent_users_deletion
BEFORE DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION prevent_delete();

触发器的管理

查看已有触发器

sql 复制代码
SELECT tgname, relname, tgtype, proname 
FROM pg_trigger 
JOIN pg_class ON pg_trigger.tgrelid = pg_class.oid
JOIN pg_proc ON pg_trigger.tgfoid = pg_proc.oid
WHERE NOT tgisinternal;

删除触发器

sql 复制代码
DROP TRIGGER IF EXISTS user_insert_trigger ON users;

删除触发器函数

sql 复制代码
DROP FUNCTION IF EXISTS log_user_insert();
相关推荐
东北小狐狸-Hellxz2 小时前
Redis 哨兵搭建+ACL权限控制
数据库·redis
研究员子楚3 小时前
GEO行业发展标准体系白皮书V2.0-第09卷 · 适配篇:硅基主权伦理宪章与行业适配宣言
数据库·人工智能·geo
l134062082354 小时前
鸿蒙实战:RDB 数据库设计与 DatabaseService
数据库·华为·harmonyos·鸿蒙系统
山峰哥4 小时前
数据库工程与索引策略实战指南‌
服务器·数据库·sql·oracle·深度优先
谙忆4 小时前
图片版权保护工程实战:明水印、盲水印(DCT隐写)、Referer防盗链与签名URL怎么落地
数据库
KaMeidebaby5 小时前
卡梅德生物技术快报|抗体合成:多肽抗体合成工程化方案:Nsp2 保守肽多抗制备与多维度验证
前端·网络·数据库·人工智能·算法
xfhuangfu5 小时前
19c CDB架构下的数据库启动和停止
数据库·架构
神道君天下5 小时前
填充与积累:积分与面积的可视化
数据库·oracle
爱折腾的小黑牛5 小时前
小程序云开发数据模型设计:礼账系统的三表结构
数据库·架构
爱折腾的小黑牛5 小时前
礼账小程序的数据安全方案:加密与备份
数据库·安全