MySQL中同一事件和时机的多个触发器严格按创建时间升序执行,无法动态干预;BEFORE在语句前、AFTER在语句成功后运行,时序固定;强顺序依赖应改用单触发器调用存储过程实现。
触发器执行顺序由定义顺序决定,但不能动态干预
MySQL 中同一事件(如 INSERT)和同一时机(BEFORE 或 AFTER)下多个触发器的执行顺序,**严格按创建时间先后(即 CREATED 时间戳)升序执行**。你无法用 ORDER BY、权重字段或执行优先级语法控制它——MySQL 不提供此类机制。
- 若需特定顺序,必须按目标顺序依次
CREATE TRIGGER;先建的先执行,后建的后执行 -
DROP再重建会改变CREATED时间,从而影响顺序,慎用 - 不同表的触发器互不影响,不存在跨表排序问题
BEFORE 和 AFTER 触发器之间有强制时序,不可颠倒
BEFORE 触发器总在语句实际执行前运行,AFTER 触发器总在语句成功执行后(且事务未提交前)运行。这个时序是硬性规则,不受触发器定义顺序影响。
-
BEFORE INSERT可修改NEW值,影响最终插入内容;AFTER INSERT读到的是已写入的值 - 若
BEFORE触发器中抛出异常(如SIGNAL SQLSTATE '45000'),整个语句中止,AFTER触发器不会执行 - 在事务中,
AFTER触发器看到的是当前事务的中间状态,不是最终提交结果
同一张表上多个 BEFORE INSERT 触发器怎么排?看 CREATE 时间
假设对表 orders 创建了两个 BEFORE INSERT 触发器:
CREATE TRIGGER tr_orders_before_1 BEFORE INSERT ON orders FOR EACH ROW SET NEW.created_at = NOW(); CREATE TRIGGER tr_orders_before_2 BEFORE INSERT ON orders FOR EACH ROW SET NEW.status = 'pending';
只要 tr_orders_before_1 先建,它就一定先执行;NEW.created_at 被设好后,tr_orders_before_2 才能读到该值(如果它需要)。但注意: