PostgreSQL中触发器启用状态需查pg_trigger表的tgenabled字段:O为启用,D为禁用,R为仅复制生效,A为始终启用;须关联pg_class获取表名。

查 PostgreSQL 中触发器启用状态用 pg_trigger
PostgreSQL 不像 MySQL 那样直接在 information_schema 里暴露触发器启用/禁用状态,得查系统表。核心是 pg_trigger 表里的 tgenabled 字段:值为 O 表示启用,D 是禁用,R 是只读(只在复制中生效),A 是始终启用(忽略 session_replication_role)。配合 pg_class 和 pg_namespace 才能关联到具体表名。
实操建议:
- 先确认目标表的
oid:SELECT oid, relname FROM pg_class WHERE relname = 'your_table_name' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');
- 再查该表所有触发器及状态:
SELECT tgname, tgenabled, tgisinternal FROM pg_trigger WHERE tgrelid = your_table_oid;
把上面查出的oid替换进去 - 想一步到位(推荐):
SELECT t.tgname, t.tgenabled, t.tgisinternal, c.relname AS table_name FROM pg_trigger t JOIN pg_class c ON t.tgrelid = c.oid WHERE c.relname = 'your_table_name' AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');
MySQL 查触发器状态只能看定义,没有运行时开关
MySQL 的 TRIGGER 对象本身没有“启用/禁用”状态字段——它一旦创建就始终生效,除非被 DROP 或 ALTER TABLE DISABLE TRIGGER(但注意:这个语法在 MySQL 中并不存在)。很多人误以为 SHOW TRIGGERS 会返回状态,其实它只返回定义、事件、时机等元信息,不反映是否激活。
实操建议:
- 查某张表的触发器列表:
SHOW TRIGGERS LIKE 'your_table_name';
- 确认触发器是否存在且有效,唯一可靠方式是检查其定义是否完整、引用对象是否存在、语法是否合法;
information_schema.TRIGGERS表里也没有等价于tgenabled的字段 - 若需临时停用,只能用
DROP TRIGGER+ 后续重建,或在触发器逻辑内加条件开关(比如查某个配置表或 session 变量)
SQL Server 中用 sys.triggers 查 is_disabled
SQL Server 明确提供了布尔字段 is_disabled,查起来最直观。只要连接到对应数据库,就能直接关联表名查出所有触发器及其开关状态。
实操建议:
- 查当前库中某表的所有触发器状态:
SELECT name, is_disabled, is_instead_of_trigger FROM sys.triggers WHERE parent_id = OBJECT_ID('your_table_name'); -
is_disabled = 1表示已禁用,= 0表示启用;is_instead_of_trigger区分是INSTEAD OF还是AFTER类型 - 注意权限:需要
VIEW DEFINITION权限才能看到sys.triggers中的行,否则可能查不到结果
触发器状态不是跨数据库一致的概念
不同数据库对“触发器是否生效”的实现机制差异很大:PostgreSQL 用 tgenabled 控制执行链路,SQL Server 用 is_disabled 硬开关,而 MySQL 根本没提供运行时控制能力。这意味着写迁移脚本或统一监控时,不能假设存在通用字段。
容易踩的坑:
- 在 PostgreSQL 中把
tgenabled = 'D'当成“删除”,其实只是禁用,pg_trigger记录仍在 - 在 SQL Server 中,
DISABLE TRIGGER操作不会影响已开始的事务,但新事务会立即生效 - MySQL 用户试图用
information_schema.TRIGGERS的某个字段判断状态,结果发现根本没有对应列
真要统一管理,得按数据库类型分别适配查询逻辑,别指望一条 SQL 走天下。

















