最可靠方法是直接查sys.triggers的is_disabled字段:0启用、1禁用,且必须用parent_id=OBJECT_ID('目标对象')精确匹配,否则漏查;MySQL则须查information_schema.TRIGGERS中STATUS、EVENT_OBJECT_TABLE和EVENT_MANIPULATION三者是否全部匹配。

直接查 sys.triggers 的 is_disabled 字段最可靠
SSMS 界面右键显示“已禁用”可能滞后或错判,SHOW TRIGGERS 在 MySQL 里不返回状态,SQL Server 唯一可信的依据就是系统视图 sys.triggers 中的 is_disabled 字段:0 表示启用,1 表示禁用。
必须配合 parent_id 精确匹配目标对象,否则查不到:
-
parent_id = OBJECT_ID('dbo.YourTable')—— 如果触发器建在表上,就用这张表的OBJECT_ID() -
parent_id = OBJECT_ID('dbo.YourView')—— 如果触发器绑在视图上,就得用视图的OBJECT_ID(),不能用底层表的 - 跨 schema 时漏写
dbo.或其他 schema 名,会导致查到空结果
查触发器状态时别漏掉 EVENT_MANIPULATION 和表名校验
尤其在自动化脚本或多人协作环境里,仅看 is_disabled 不够。一个触发器即使启用,也可能因事件类型不匹配而静默失效:
-
EVENT_OBJECT_TABLE必须和你当前操作的表名完全一致(含 schema) -
EVENT_MANIPULATION必须匹配实际操作,比如你执行的是UPDATE,但触发器定义是INSERT,它就不会跑 - MySQL 8.0+ 中,
UPDATE t SET status = status这类无实际变更的语句,引擎直接跳过触发器——这不是被禁用,是设计行为
为什么不能只依赖 SELECT name FROM sys.triggers
这条语句只列出存在哪些触发器,完全不反映启用状态。常见误判场景:
- 执行了
DISABLE TRIGGER trg_log ON dbo.Orders,但没验证,以为“命令成功=已禁用” - 权限不足导致禁用失败,
sys.triggers.is_disabled仍是 0,但报错被忽略 - 触发器建在视图上,却用基础表的
OBJECT_ID()去查,结果为空,误以为“没触发器”
非企业版只能靠定时轮询,别指望自动告警
SQL Server 默认不记录 DISABLE TRIGGER 或 ENABLE TRIGGER 操作,这些命令不写事务日志,也不进默认跟踪。企业版可用 DATABASE AUDIT SPECIFICATION 捕获 SCHEMA_OBJECT_CHANGE_GROUP,但标准版、Web 版只能自己动手:
- 写个每小时运行一次的作业,查
sys.triggers中is_disabled = 1的项,写入告警表 - 把检查逻辑嵌入部署脚本,在上线前强制校验关键触发器状态
- 禁用操作本身不可回滚,也没日志可溯,所以“查状态”不是事后补救,而是每次操作后的必要验证步骤
INSERT 直接报错中断。

















