gpt4 book ai didi

postgresql - 选择更新查询返回基数冲突

转载 作者:行者123 更新时间:2023-11-29 12:50:03 28 4
gpt4 key购买 nike

我们在 Google 托管的云数据库中的 Postgres 9.6.10 中运行此查询:

WITH update AS
(UPDATE cart SET loyalty = loyalty || jsonb_insert('{}', '{coupon}', loyalty#>'{scan_coupon}' || $1) WHERE id =
(SELECT id FROM cart WHERE id = $2 AND status = $3 and item_version = $4 FOR UPDATE) returning *)
SELECT * FROM updated

cart 是一个以 id 作为主键的表。 loyalty 是一个 jsonb 列,item_version 是一个在某些操作上递增的函数,但在更新 item_version 之前预计会发生几次更新。 status 是一个枚举类型。

在高并发更新下我们很少会遇到如下错误:

Cardinality_violation, file: "nodeSubplan.c", line: "1127", message: "more than one row returned by a subquery used as an expression", pg_code: "21000", routine: "ExecSetParamPlan", severity: "ERROR", unknown: "ERROR"

我已经确认 $2 实际上是一个整数并指向一个现有的行,因为 id 是主键,所以我看不出它怎么会返回不止一排。

SELECT FOR UPDATE 是有问题的查询吗?如果 id 是主键,该查询如何返回多行。

最佳答案

看起来你可以简化为:

UPDATE cart
SET loyalty = loyalty || jsonb_build_object('coupon', loyalty->'scan_coupon') || $1
WHERE id = $2
AND status = $3
AND item_version = $4
RETURNING *;

UPDATE 以与嵌套的 SELECT ... FOR UPDATE 相同的方式锁定行。

jsonb_build_object()更简单,与您的 jsonb_insert() 相同。或者更简单,但:

SET    loyalty = jsonb_insert(loyalty, '{coupon}', loyalty->'scan_coupon') || $1

我和你一样惊讶,子查询(你不需要)会以某种方式返回不止一行。似乎不可能。您确定这是错误消息的来源吗?

关于postgresql - 选择更新查询返回基数冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56435529/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com