查询 sys.triggers 可获取触发器名称、启用状态(is_disabled=0启用)、类型(is_instead_of_trigger=1为INSTEAD OF)、创建修改时间,并需关联 sys.tables 按表名过滤;DML事件类型需联查 sys.trigger_events;DDL触发器不关联 sys.tables;跨架构需校验 schema_id。

查 sys.triggers 看触发器基本信息和启用状态
SQL Server 把触发器元数据存在 sys.triggers 视图里,其中 is_disabled 字段直接反映启用状态:0 表示启用,1 表示禁用。必须关联 sys.tables 或用 parent_id 过滤目标表,否则会返回数据库中所有触发器。
执行以下查询(把 'YourTableName' 替成实际表名):
SELECT
t.name AS trigger_name,
t.is_disabled,
CASE WHEN t.is_disabled = 0 THEN 'ENABLED' ELSE 'DISABLED' END AS status,
t.create_date,
t.modify_date
FROM sys.triggers t
INNER JOIN sys.tables tbl ON t.parent_id = tbl.object_id
WHERE tbl.name = 'YourTableName';
区分 DML 触发器类型(INSERT/UPDATE/DELETE)
sys.triggers 本身不直接存触发事件类型,得查 sys.trigger_events 关联视图。一个触发器可能响应多个事件(比如同时对 INSERT 和 UPDATE 生效),所以结果行数可能多于触发器数量。
补充事件信息的写法:
SELECT
t.name AS trigger_name,
te.type_desc AS event_type,
t.is_disabled
FROM sys.triggers t
INNER JOIN sys.tables tbl ON t.parent_id = tbl.object_id
INNER JOIN sys.trigger_events te ON t.object_id = te.object_id
WHERE tbl.name = 'YourTableName'
ORDER BY t.name, te.type_desc;
-
type_desc值常见为INSERT、UPDATE、DELETE、CREATE_TABLE(DDL 触发器)等 - 如果只关心 DML 触发器,可在
WHERE加te.type IN (1, 2, 3)(对应 INSERT=1, UPDATE=2, DELETE=3) - DDL 触发器的
parent_id指向sys.servers或为 0,不会出现在sys.tables关联结果里——这点容易漏查
确认触发器是否为 INSTEAD OF 类型
DML 触发器分 AFTER 和 INSTEAD OF 两类,行为差异极大。sys.triggers 的 is_instead_of_trigger 字段就是干这个的:1 表示是 INSTEAD OF,0 是 AFTER(或 FOR)。
加到基础查询里即可:
SELECT
t.name AS trigger_name,
t.is_disabled,
t.is_instead_of_trigger,
CASE WHEN t.is_instead_of_trigger = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END AS trigger_type
FROM sys.triggers t
INNER JOIN sys.tables tbl ON t.parent_id = tbl.object_id
WHERE tbl.name = 'YourTableName';
- 视图上只能建
INSTEAD OF触发器,表上两者都支持 -
INSTEAD OF触发器会替代原操作执行,AFTER则在操作完成后触发——误判类型可能导致调试逻辑错乱
注意权限和跨架构场景
如果表在非 dbo 架构下(比如 sales.Orders),仅靠 tbl.name = 'Orders' 可能匹配到同名不同架构的表。稳妥做法是同时比对 SCHEMA_NAME(tbl.schema_id)。
- 没有
VIEW DEFINITION权限时,sys.triggers仍可查出名称和状态,但无法看到触发器定义(OBJECT_DEFINITION()会返回 NULL) - 系统表如
sys.objects不建议直接查触发器,因为type = 'TR'的条目不包含is_disabled等关键字段,容易遗漏状态判断 - 临时表上的触发器不会出现在
sys.triggers中,因为它们属于会话级对象
真正要动手改状态时,记得用 ENABLE TRIGGER 或 DISABLE TRIGGER 语句,而不是去更新系统视图——后者不被允许,且会破坏元数据一致性。

















