【发布时间】:2018-07-27 04:25:23
【问题描述】:
我有一个表t 有几列,我们将它们命名为a、b 和c。我还有一个 state 列,它指示当前状态。还有一个id 列。
我想编写以下查询:总是更新列a,但b 和c 仅当应用程序state 仍然等于数据库state 时。这里,state 列用于乐观锁定。
我将这个查询写成如下:
UPDATE t
SET a = $a$,
b = (CASE WHEN state = $state$ THEN $b$ ELSE b END),
c = (CASE WHEN state = $state$ THEN $c$ ELSE c END)
WHERE id = $id$ AND
(
a != $a$ OR
b != (CASE WHEN state = $state$ THEN $b$ ELSE b END) OR
c != (CASE WHEN state = $state$ THEN $c$ ELSE c END)
)
这里,$id$, $a$, ... 是来自应用程序的输入变量。 WHERE 子句的第二部分是避免不会有效更新任何内容的更新。
此查询按预期工作,但非常笨拙。我多次重复相同的条件。我正在寻找一种以更优雅的方式重写此查询的方法。如果这是一个简单的SELECT 查询,我可以用LATERAL JOIN 做一些事情,但我看不到如何在这里应用它。
如何改进这个查询?
【问题讨论】:
-
你能说明你想用 a 做什么吗? “始终更新 a 列”或“避免不会有效更新任何内容的更新。”?
-
列
a应更新,无论state。列b和c应由state保护。WHERE子句是为了防止zero updates:当新行与当前行完全相同时,我不希望我的 MVCC 数据库创建新行。
标签: sql postgresql