我想更新一批行,但前提是该批中的所有行都符合条件。
示例表:
create table thing (
id int primary key,
ref int
);
示例数据:
INSERT INTO thing (id, ref)
VALUES
(1, NULL)
, (2, NULL)
, (3, 1)
, (4, 1);
错误查询示例 - 这会更新第 1 行和第 2 行,但会保留第 3 行(不需要):
UPDATE thing
SET ref = 2
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NULL;
目标:单个查询,其中之一:更新所有匹配的行;或 2:什么都不做,并以某种方式通知我(例如更新了 0 行)所以可以发出警告。
编辑 - 此处示例:http://sqlfiddle.com/#!17/f9ad9/4
答案 0 :(得分:1)
如果存在满足部分 WHERE
条件但不是所有连词项的行,则更新全部或不更新。
UPDATE thing
SET ref = 2
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NULL
AND NOT EXISTS (select 1 from thing t where t.id = ANY(ARRAY[1,2,3]) and t.ref IS NOT NULL or not(t.id = ANY(ARRAY[1,2,3])) AND t.ref IS NULL)
或者,当 WHERE 中的原始连词有两个以上的词时
UPDATE thing
SET ref = 2
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NULL
AND NOT EXISTS (select 1
from thing t
where ( t.id = ANY(ARRAY[1,2,3]) or t.ref IS NULL)-- disjunction of terms of original conjunction
and ( not(t.id = ANY(ARRAY[1,2,3]) or t.ref IS NOT NULL) --disjunction of negations of terms of original conjunction
);
答案 1 :(得分:1)
with pre_condition as
(
select
count(*) filter (where id = ANY(ARRAY[1,2,3])) batch_count,
count(*) filter (where id = ANY(ARRAY[1,2,3]) AND ref IS NULL) set_count
from thing
)
UPDATE thing
SET ref = 2
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NULL
and (select batch_count = set_count from pre_condition)
returning id;
答案 2 :(得分:0)
这是我解决自己问题的方法:W3Schools JSON.Parse()
UPDATE thing
SET ref = 2
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NULL
AND NOT EXISTS ( -- if anything returns here — nothing will update
SELECT 1
FROM thing
WHERE id = ANY(ARRAY[1,2,3]) AND ref IS NOT NULL
)
RETURNING id;