在 Postgres 13 中,我有一个经常更新的表。但是,更新查询相当复杂,并且多次使用相同的值。因此,使用 CTE 似乎是一件合乎逻辑的事情。
一个简化的示例如下所示:
WITH my_cte AS (
SELECT
my_id,
CASE WHEN my_value1 > 100 THEN 50 ELSE 10 END AS my_addition
FROM my_table
WHERE my_id = $1
)
UPDATE my_table
SET my_value1 = my_table.my_value1 + my_cte.my_addition,
my_value2 = my_table.my_value2 + my_cte.my_addition
FROM my_cte
WHERE my_table.my_id = my_cte.my_id
现在我想知道:如果在SELECT
CTE 和之间UPDATE
,表被另一个查询更新,my_value1
因此发生变化,计算会my_addition
在发生时变得过时和错误UPDATE
。会不会出现这样的情况?还是 Postgres 自动设置隐式锁?
如果 Postgres 在这里没有魔法,我需要自己处理它:在 CTE 中做就足够了FOR UPDATE
吗SELECT
?
抱歉,如果我没有在这里说清楚:这不是我想“看到”那些并发修改,我想阻止它们,即一旦计算SELECT
完成,在完成之前没有其他查询可能修改该行UPDATE
。
在现实生活中,我在这里嘲笑的CASE WHEN my_value1 > 100 THEN 50 ELSE 10 END
是大约 20 行长,我在UPDATE
. 由于我是“不要重复自己”的忠实粉丝,我认为 CTE 是要走的路。或者有没有更好的方法来避免在UPDATE
没有 CTE 的情况下复制和粘贴?