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
相关产品推荐
相关产品推荐

