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

PostgreSQL库存校验触发器触发无限循环栈溢出问题咨询

问题根因
  • 触发无限递归的直接原因:你在绑定了warehouse表UPDATE事件的触发器内部,再次执行了UPDATE warehouse语句,这个更新操作会再次触发同一个触发器,无限递归调用最终超出栈深度限制,触发栈溢出报错。
  • 实现逻辑错误:BEFORE UPDATE行级触发器不需要手动编写SQL修改原表数据,校验通过后直接返回NEW记录,数据库会自动用NEW的字段值完成行更新;如果校验不通过直接抛出错误即可终止更新操作。
  • 冗余查询问题:你代码中查询warehouse表拿到的print.quantity和触发器内置的OLD.quantity(更新前的库存值)完全一致,额外关联drugstore表也没有用到任何该表的字段,属于完全冗余的逻辑。
  • 你的更新语句本身存在语法错误,warehouseset中间缺少空格,正确写法为update warehouse set quantity=2 where iddrug=1 AND iddrugstore=2;
正确实现代码

你需要的「更新后库存低于0则阻止更新」功能可以直接简化为以下逻辑:

-- 创建校验库存的触发器函数
CREATE OR REPLACE FUNCTION check_warehouse_quantity()
RETURNS TRIGGER 
LANGUAGE PLPGSQL
AS
$$
BEGIN
    -- 校验更新后的库存值是否小于0
    IF NEW.quantity < 0 THEN
        -- 抛出错误终止更新
        RAISE EXCEPTION '药品ID: % 在门店ID: % 的库存不能为负数', NEW.iddrug, NEW.iddrugstore;
    END IF;
    -- 校验通过返回NEW即可,数据库会自动完成更新
    RETURN NEW;
END;
$$;

-- 先删除原有错误触发器
DROP TRIGGER IF EXISTS triggerBuyArticle ON warehouse;

-- 创建新的触发器,仅在quantity字段更新时触发
CREATE TRIGGER trigger_check_quantity_before_update
BEFORE UPDATE OF quantity ON warehouse
FOR EACH ROW
EXECUTE FUNCTION check_warehouse_quantity();
注意事项

如果你的业务场景是处理出库扣减库存,建议在出库单据表上编写触发器修改仓库库存,不要在仓库表的触发器中再次修改仓库表,从根源避免递归触发的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:57:03