查 pg_trigger 系统表是最直接的方法,需关联 pg_class 和 pg_namespace 以准确获取指定 schema 下表的触发器信息,包括名称、状态(tgenabled)、定义及是否禁用。

查 pg_trigger 系统表是最直接的方法
PostgreSQL 把触发器元信息全存在 pg_trigger 里,只要连上数据库、有 SELECT 权限就能查。关键是要关联 pg_class(找表 OID)和 pg_namespace(处理 schema),否则容易漏掉非 public 下的表。
常用实操语句:
SELECT tgname AS trigger_name,
relname AS table_name,
nspname AS schema_name,
tgenabled AS enabled,
pg_get_triggerdef(oid) AS definition
FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE NOT t.tgisinternal
AND c.relname = 'your_table_name'
ORDER BY nspname, relname;
-
c.relname = 'your_table_name'必须小写匹配(除非建表时加了双引号) -
NOT t.tgisinternal过滤掉系统自建的触发器(比如RI_FKey_*约束触发器) -
pg_get_triggerdef(oid)能还原出原始CREATE TRIGGER语句,比看字段拼更可靠
用 \d+ 在 psql 里快速查看(适合开发调试)
如果你在终端用 psql 连着库,\d+ 命令比写 SQL 更快,它会把表结构、列类型、索引、约束,还有触发器一并列出来。
执行方式:
\d+ your_table_name
- 输出里触发器部分标着
Triggers:,每行一个,格式是trigger_name BEFORE/AFTER/INSTEAD OF events ON table_name FOR EACH ROW/STATEMENT WHEN (condition) - 注意:如果触发器定义太长,
\d+可能只显示缩略版,这时得回退到pg_trigger查完整定义 - 该命令不跨 schema 自动搜索,必须指定带 schema 的表名,比如
\d+ myschema.mytable
触发器被禁用但没删,tgenabled 字段会暴露这点
触发器可以被禁用而不删除,比如用 ALTER TABLE ... DISABLE TRIGGER。这时候它依然存在于 pg_trigger 中,只是 tgenabled 值不是 O(enabled)——可能是 D(disabled)、R(replica)、A(always)。
-
tgenabled = 'D'表示手动禁用,SQL 仍生效但不会触发 -
tgenabled = 'R'表示只在备库启用(常用于逻辑复制场景) - 别只查
tgname就认为“有触发器=会执行”,得看这个字段
跨 schema 查询时别漏掉 pg_namespace 关联
很多线上库把表分在不同 schema(比如 sales、log),如果只按 relname 过滤,会把同名表(如多个 schema 下都有 orders)的触发器全混在一起。
正确做法是显式 join pg_namespace 并筛选 nspname:
AND n.nspname = 'sales'
- 省略这步,可能查到其他 schema 下同名表的触发器,误判业务逻辑
-
information_schema.triggers虽然也能查,但它不暴露tgenabled和内部 OID,也不包含 disabled 触发器,实用性不如直接查系统表
实际查的时候,schema 名、表名大小写、是否禁用——这三个点最容易漏,尤其当触发器是别人建的、又没文档时。











