You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建UPDATE触发器更新同表字段时,是否会重复触发该触发器?

关于UPDATE触发器修改同表字段是否会递归触发的问题

这个问题问得太实用了——毕竟一不小心就可能踩进无限递归的坑!答案其实得看你使用的数据库系统,不同数据库的默认规则和处理逻辑差异不小:

MySQL 场景

MySQL 默认是禁止同表触发器递归触发的。也就是说,当你的触发器里对同一张表执行UPDATE操作时,不会再次触发同一个触发器。

举个例子,你写的这个需求:

CREATE TRIGGER trg_item_update_cost
AFTER UPDATE ON Item
FOR EACH ROW
BEGIN
    -- 即使不加判断,MySQL也不会递归触发这个触发器
    UPDATE Item SET cost = 99 WHERE id = NEW.id;
END;

不过还是建议加个判断条件,避免无意义的更新操作:

CREATE TRIGGER trg_item_update_cost
AFTER UPDATE ON Item
FOR EACH ROW
BEGIN
    IF NEW.cost != 99 THEN
        UPDATE Item SET cost = 99 WHERE id = NEW.id;
    END IF;
END;

SQL Server 场景

SQL Server 的规则相对灵活,默认情况下直接递归触发是被禁止的(通过 RECURSIVE_TRIGGERS 数据库选项控制,默认值为 OFF),但间接递归(比如触发器A触发触发器B,再触发触发器A)是否允许取决于 Nested Triggers 选项(默认开启)。

如果你的场景是触发器自己更新同表字段,默认不会递归触发;但如果手动开启了 RECURSIVE_TRIGGERS,就会触发直到达到默认32层的递归限制,甚至报错。所以同样建议在触发器里加条件判断,或者保持默认的递归禁用设置。

PostgreSQL 场景

PostgreSQL 默认允许递归触发,而且有默认100层的递归深度限制。如果你的触发器里没有加判断,直接更新同表字段,会陷入反复触发的循环,直到超过深度限制抛出错误。

这里更推荐用 BEFORE UPDATE 触发器直接修改字段值,而不是用 AFTER UPDATE 再去执行UPDATE语句——这样既高效,又能从根源避免递归问题:

CREATE OR REPLACE FUNCTION set_cost_to_99()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.cost != 99 THEN
        NEW.cost := 99;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_item_update_cost
BEFORE UPDATE OF cost ON Item
FOR EACH ROW
EXECUTE FUNCTION set_cost_to_99();

总结建议

  • 不同数据库的默认行为差异很大,一定要结合你使用的数据库文档确认规则
  • 无论用哪种数据库,在触发器里加条件判断都是好习惯——只在需要修改的时候执行操作,避免无意义的触发和性能损耗
  • 优先考虑用 BEFORE 触发器直接修改字段值,而非 AFTER 触发器再执行表更新,能有效规避递归风险

内容的提问来源于stack exchange,提问作者Liam neesan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:00:24