postgresql触发器是一种由数据库事件自动调用的数据库对象,常与触发器函数配合使用,用于在插入、更新或删除数据时执行自定义逻辑。合理设计触发器可以保障数据一致性,减少应用层代码负担。

一、postgresql触发器设计基础
在postgresql中,触发器必须绑定到一个触发器函数上,函数返回类型固定为trigger。设计步骤通常分为两步:先写函数,再挂触发器。
1. 创建触发器函数
使用CREATE FUNCTION定义函数,内部可通过TG_OP、NEW、OLD等特殊变量获取触发上下文。
CREATE OR REPLACE FUNCTION log_user_change()
RETURNS trigger AS $$
BEGIN
-- 如果是插入操作,将新用户名写入日志表
IF TG_OP = 'INSERT' THEN
INSERT INTO user_log(username, action) VALUES (NEW.name, 'insert');
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
2. 挂载触发器到表
通过CREATE TRIGGER语句将函数绑定到目标表,并指定触发时机与事件。
CREATE TRIGGER trg_user_insert AFTER INSERT ON users FOR EACH ROW EXECUTE FUNCTION log_user_change();
二、触发器执行流程解析
当对表执行DML语句时,postgresql按如下顺序处理触发器:
- 解析并执行SQL命令,进入触发器管理模块。
- 按声明顺序依次执行该表上所有BEFORE行级或语句级触发器。
- 完成实际数据修改操作。
- 按声明顺序执行所有AFTER触发器。
- 返回结果给客户端。
触发时机与粒度
| 类型 | 说明 |
|---|---|
| BEFORE ROW | 每行修改前触发,可修改NEW值或跳过操作 |
| AFTER ROW | 每行修改后触发,常用于写日志 |
| STATEMENT | 整个SQL语句执行前后各触发一次 |
三、设计注意事项
设计postgresql触发器时,应避免在触发器函数内再次修改同一表引发递归;同时行级触发器在大批量操作中可能带来性能开销,可评估使用语句级触发器。另外,在函数中明确RETURN值,行级BEFORE触发器返回NULL会中止该行操作。
示例:若希望在删除用户前校验状态,可用BEFORE DELETE行级触发器,不满足条件时抛异常或返回NULL。
CREATE OR REPLACE FUNCTION block_active_delete()
RETURNS trigger AS $$
BEGIN
IF OLD.status = 'active' THEN
RAISE EXCEPTION '不能删除活跃用户';
END IF;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_block_del
BEFORE DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION block_active_delete();
四、小结
postgresql触发器的设计核心是先写返回trigger的函数,再按业务需要选择时机与粒度挂载。理清执行流程有助于排查数据异常与性能瓶颈,让数据库层逻辑更可靠。
postgresql触发器trigger执行流程数据库修改时间:2026-07-24 16:06:20