唯一可靠方式是先查 information_schema.triggers 获取完整元数据,再用 show create trigger 获取含 definer、sql_mode 等上下文的可部署定义;show triggers 易截断、缺关键信息且不支持条件筛选。

直接查 INFORMATION_SCHEMA.TRIGGERS 表,再用 SHOW CREATE TRIGGER 拿定义——这是唯一可靠、不漏字段、不依赖当前库状态的方式。
为什么不能只用 SHOW TRIGGERS
SHOW TRIGGERS 看起来最方便,但实际踩坑最多:
- 没先执行
USE your_db就运行,立刻报错ERROR 1046 (3D000): No database selected - 即使加了
FROM db_name,Statement字段默认只显示前 64 字符,关键逻辑被截断(比如长 INSERT 或嵌套 IF) - 不返回
DEFINER、字符集、sql_mode等迁移必需信息 - 无法 WHERE 筛选“所有 AFTER UPDATE 触发器”这类条件,只能靠人眼扫
SELECT 从 INFORMATION_SCHEMA.TRIGGERS 查全量元数据
这张表是 MySQL 5.7+ 的权威来源,字段完整、权限可控、支持任意过滤:
- 查当前库所有触发器:
SELECT TRIGGER_NAME, EVENT_OBJECT_TABLE, ACTION_TIMING, EVENT_MANIPULATION, ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA = DATABASE(); - 查某张表上的触发器:
WHERE TRIGGER_SCHEMA = 'myapp' AND EVENT_OBJECT_TABLE = 'orders' - 查所有 BEFORE INSERT 触发器:
WHERE ACTION_TIMING = 'BEFORE' AND EVENT_MANIPULATION = 'INSERT' -
ACTION_STATEMENT是触发器主体 SQL,但注意:它已被 MySQL 内部转义,可能含\n或双引号,不能直接复制执行
用 SHOW CREATE TRIGGER 拿可部署的完整定义
只有这个命令能还原出带 DEFINER、sql_mode、原始换行和注释的建触发器语句:
- 语法必须带库名:
SHOW CREATE TRIGGER myapp.before_update_user;—— 漏掉myapp.会报ERROR 1360 (HY000): Trigger does not exist - 触发器名区分大小写:Linux 下若创建时是
MyTrigger,查mytrigger就找不到(取决于lower_case_table_names设置) - 结果里
Trigger列才是完整语句,sql_mode列是当时创建用的模式,线上环境不一致可能导致行为差异 - 如果要批量导出所有触发器,得先从
INFORMATION_SCHEMA.TRIGGERS拿出名字列表,再拼接执行SHOW CREATE TRIGGER,没法一步到位
真正容易被忽略的是:触发器定义里隐含的权限上下文(DEFINER)和 SQL 模式。直接复制 ACTION_STATEMENT 去另一个环境执行,大概率失败——必须用 SHOW CREATE TRIGGER 拿到带上下文的完整语句。











