我有一个表有两列是唯一的,如果第一列(或两列)有冲突,我想要upsert,但如果只有第二列有冲突,则不执行任何操作。这可能吗?
CREATE TABLE test (
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
status VARCHAR(127)
);
以下是检查电子邮件冲突的方法:
INSERT INTO test(username, email)
VALUES ('test', 'test@test.test')
ON CONFLICT(email) DO UPDATE SET status='upserted';
但是我想做这样的事情(下面的语法无效):
(INSERT INTO test(username, email)
VALUES ('test', 'test@test.test')
ON CONFLICT(email) DO UPDATE SET status='upserted')
ON CONFLICT DO NOTHING;
答案 0 :(得分:1)
是的,你可以这样做,但它需要一些条件技巧。
首先,您只能有一个ON CONFLICT
子句,但此子句可以指定多个列,并在其上定义约束。在你的情况下,ON CONFLICT (username, email)
。当其中一列或两列触发冲突时,conflict_action
会启动。
其次,conflict_action
子句应将候选行中的值(由EXCLUDED
引用)与当前值进行比较,并采取适当的措施。 DO NOTHING
实际上不可能,但您可以将旧值分配给新行,因此效果相同(但更新将会发生)。不漂亮,但它看起来有点像这样:
INSERT INTO test(username, email)
VALUES ('test', 'test@test.test')
ON CONFLICT(username, email) DO UPDATE
SET status = CASE WHEN username != EXCLUDED.username -- only email offending
THEN status -- so "do nothing"
ELSE 'upserted' -- some other action
END;