




MySQL触发器执行顺序由类型和创建时间决定:先BEFORE后AFTER,同类型按创建时间升序执行;无法直接修改顺序,需删重建;BEFORE可修改NEW值并透传,AFTER不可修改;嵌套触发器需限制递归深度以防风险。
MySQL 中同一事件(如 INSERT)上可以定义多个触发器,但它们的执行顺序不是随机的:先执行 BEFORE 类型,再执行 AFTER 类型;同为 BEFORE 或同为 AFTER 时,按创建时间升序执行(即先建的先触发)。没有显式控制执行优先级的语法(比如 DEFINER 或 ORDER 子句)

CREATE TRIGGER 语句本身不支持指定顺序。
MySQL 不提供 ALTER TRIGGER 语法,也不能给触发器设权重或序号。若需调整顺序,只能删掉再重建——但要注意依赖关系:
DROP TRIGGER IF EXISTS 后必须立刻用新顺序 CREATE TRIGGER,否则中间窗口可能被业务写入绕过逻辑DROP+CREATE 可能导致从库触发器缺失或顺序错乱,建议在维护窗口停写并校验只有 BEFORE INSERT 和 BEFORE UPDATE 允许赋值给 NEW.column_name,这个修改会透传给后续所有同类型触发器,最终也作用于实际插入/更新的数据。而 AFTER 触发器读到的 NEW 已是最终值,不能修改。
CREATE TRIGGER tr_before_insert_user BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.created_at = NOW(); SET NEW.status = IF(NEW.status IS NULL, 'active', NEW.status); END;
如果还有另一个 BEFORE INSERT 触发器在它之后创建,它看到的 NEW.created_at 就已是 NOW() 的值,而非原始 NULL。
MySQL 默认允许触发器内执行 DML 并再次激活其他触发器(即嵌套),最大深度由系统变量 max_sp_recursion_depth 控制(默认 0,表示不限制)。这容易引发意料外的连锁反应:
UPDATE 触发器里更新了另一张表,恰好那张表也有 AFTER UPDATE 触发器,就构成嵌套ERROR 1456 (HY000): Recursive limit 0 (as set by the max_sp_recursion_depth variable)
生产环境建议显式设限:SET GLOBAL max_sp_recursion_depth = 1;,强制只允许一级触发(主语句 → 触发器),避免隐式扩散。