假设我们有一个这样的表:
CREATE TABLE ctest (
ID INTEGER,
Value TEXT,
Age INTEGER,
Weight INTEGER,
PRIMARY KEY (ID, Value), UNIQUE (Age, Weight));
我们已经有几行:
INSERT INTO ctest (ID, Value, Age, Weight) VALUES (0, 'second', 1, 2);
INSERT INTO ctest (ID, Value, Age, Weight) VALUES (0, 'first', 1, 3);
假设我们现在要插入违反primary key
和unique
约束的行:
INSERT INTO ctest (ID, Value, Age, Weight) VALUES (0, 'second', 1, 3)
ON CONFLICT (ID, Value, Weight, Age) DO UPDATE SET
ID = EXCLUDED.ID,
Value = EXCLUDED.Value,
Age = EXCLUDED.Age,
Weight = EXCLUDED.Weight;
不,这不起作用:我们得到no unique or exclusion constraint matching the ON CONFLICT
。
如果在创建ctest
表时,我们还添加了UNIQUE (ID, Value, Age, Weight)
约束(正如一些研究表明这可能会有所帮助),这也不起作用,但我们得到了不同的排序错误:这次是关于ctest_pkey
被违反且密钥(id, value)=(0, second)
已经存在。
那么,定义模式和拼出insert
语句的正确方法是什么,以便两行都被一个新行替换?
答案 0 :(得分:1)
INSERT语句无法在冲突时删除。
要根据来条件删除现有行,请使用WITH ... DELETE ... RETURNING
构造。
WITH del AS (DELETE FROM ctest
WHERE (Age=1 AND Weight=3)
OR (ID = 0 AND Value = 'second')
RETURNING 0, 'second', 1, 3
)
INSERT INTO ctest (ID, Value, Age, Weight)
SELECT *
FROM del
ON CONFLICT DO NOTHING