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

PostgreSQL触发器更新所有payment行而非匹配service_id对应行问题求助

问题根因

  • UPDATE payment语句未加WHERE筛选条件,执行时默认修改payment表所有行,这是全表被更新的核心原因,需要指定仅更新和当前触发事件service_id匹配的payment行。
  • 触发器绑定的表错误。当前触发器绑定在basket表的插入事件上,但你实际执行插入操作的是done_services表,正常逻辑下原有触发器不会被触发,属于表名配置错误,需要将触发器绑定到done_services表的对应事件上。

修正后的代码

1. 重写求和函数

CREATE OR REPLACE FUNCTION make_sum() RETURNS TRIGGER
AS $$
BEGIN
    -- 仅更新对应service_id的payment行,新增WHERE筛选条件
    -- 加COALESCE避免该service_id下无服务记录时sum变为NULL,默认置为0更合理
    UPDATE payment
    SET sum = (SELECT COALESCE(SUM(price), 0) FROM done_services WHERE service_id = NEW.service_id)
    WHERE service_id = NEW.service_id;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

2. 重建触发器绑定到正确的表

-- 先删除原有绑定错误的触发器
DROP TRIGGER IF EXISTS make_sum ON basket;
-- 绑定到done_services表的插入事件,如需修改、删除价格时也同步更新,可扩展触发事件
CREATE TRIGGER make_sum
AFTER INSERT ON done_services
FOR EACH ROW EXECUTE FUNCTION make_sum();

如果你需要在删除done_services记录、修改done_services的price或service_id时也同步更新payment金额,可以调整触发器触发事件为AFTER INSERT OR UPDATE OF price, service_id OR DELETE ON done_services,同时修改函数逻辑适配OLD变量场景,删除操作时使用OLD.service_id匹配需要更新的payment行即可。

验证操作

执行你的插入语句:

insert into done_services(id, service_id, price) values(uuid_generate_v4(), '76594d2f-7153-495f-9671-0ddaa331568c', 100);

执行后仅会修改payment表中service_id = '76594d2f-7153-495f-9671-0ddaa331568c'的行的sum值,其余行不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:27:04