我有一个像这样的查询
UPDATE my_table
SET my_value =
CASE WHEN random() > 0.5 THEN my_value * 2 ELSE my_value END
RETURNING *;
现在,在RETURNING
语句中,我想要一个布尔值,指示my_value
当前查询是否已更改。
假设,我不能将之前的值my_value
作为参数传递给查询。
那么,有没有办法获得类似在 之后具有不同值的列的列表UPDATE
?还是在 in 之前的状态下获取UPDATE
值RETURNING
?
在我的示例中,我当然可以将结果放入random()
CTE 中,例如
WITH random_cte AS (
SELECT random() AS my_random
)
UPDATE my_table
SET my_value =
CASE WHEN my_random > 0.5 THEN my_value * 2 ELSE my_value END
FROM random_cte
RETURNING *, my_random > 0.5 AS value_changed;
但这会使查询有些膨胀。所以我想知道我是否可以以更优雅的方式做到这一点?
这两个查询是不等价的。第一个查询将评估每一行的
VOLATILE
函数random()
,而第二个查询在 CTE 中评估一次,因此my_random
对所有行都是相同的。不,CTE 不会被内联。手册:
大胆强调我的。
但这可能只是构建测试时的一个意外。
任一查询都会更新所有行,即使没有任何变化。
为了获得
value_changed
可靠的结果,请比较 pre-UPDATE
和 post-UPDATE
值:id
是 PK 或任何其他(组合)唯一的非空列。random() > 0.5
可以true
并且my_value
仍然保持不变。想想NULL
或0
。并发写入负载下存在潜在的竞争条件。看:
如果您的用例真的那么简单(只有一个列要更新),您宁愿从一开始就禁止空更新。看: