PostgreSQL中DELETE无返回行时如何正确执行后续UPDATE操作
问题根因
你当前写法的核心问题是:PostgreSQL的DELETE语句的RETURNING子句,只有在实际删除到行的时候才会返回数据,没有匹配删除行时永远返回空结果集,你修改RETURNING里写子查询也没用,因为根本不会触发RETURNING的返回逻辑。另外你后续的UPDATE关联了del这个CTE的结果,当del是空的时候,UPDATE的WHERE条件永远不成立,自然不会执行更新操作。
修复方案
你不需要把DELETE的执行结果和UPDATE逻辑绑定,按需求顺序执行操作即可:
方案1(通用场景,优先推荐)
不管有没有删除到关联表数据,都执行指定id的outfit更新:
create function updateoutfit(_id uuid, _title text DEFAULT NULL::text) returns TABLE(id uuid, title text) language sql as $$ -- 先执行关联表删除,需要删多个表就依次加对应的DELETE语句即可 DELETE FROM outfit_garment WHERE outfit_garment.outfit_id = _id; -- 直接更新指定id的outfit,不依赖删除结果 UPDATE outfit SET title = _title WHERE id = _id RETURNING id, title; $$;
方案2(严谨场景)
只有当outfit表存在对应_id的记录时,才执行删除和更新操作,避免无效删除:
create function updateoutfit(_id uuid, _title text DEFAULT NULL::text) returns TABLE(id uuid, title text) language sql as $$ WITH target_outfit AS ( SELECT id FROM outfit WHERE id = _id -- 先校验目标outfit存在 ) , del AS ( DELETE FROM outfit_garment og USING target_outfit tof WHERE og.outfit_id = tof.id ) UPDATE outfit o SET title = _title FROM target_outfit tof WHERE o.id = tof.id RETURNING o.id, o.title; $$;
你之前修改DELETE语句RETURNING里加子查询的方案无效,是因为RETURNING子句的执行前提是DELETE实际命中了行,没有命中行时整个RETURNING块不会执行,自然不会返回任何数据。
内容的提问来源于stack exchange,提问作者Anita
相关产品推荐
相关产品推荐

