Postgres:与CASE一起使用ON CONFLICT

时间:2019-03-16 11:17:35

标签: postgresql

我正在尝试确定与CASE一起执行ON CONFLIC时应使用的确切语法。

我有一张桌子(忽略id,在这里不相关):

CREATE TABLE public.test (
    id integer NOT NULL,
    mykey integer,
    t text,
);

限制mykey必须唯一

ALTER TABLE test
ADD CONSTRAINT test_constraint UNIQUE (mykey);

让我们用一些播放条目填充它:

INSERT INTO test (mykey,t) VALUES (123,'my first value');
INSERT INTO test (mykey,t) VALUES (13,'second value');

现在,我想制作一个使用ON CONFLICT和CASE的INSERT语句,以便:如果t的新值等于旧值,则不执行任何操作,否则进行更新。

这是我到目前为止所拥有的:

INSERT INTO test (mykey,t) VALUES (123,'a new value') 
ON CONFLICT ON CONSTRAINT test_constraint 
DO CASE t
WHEN excluded.t THEN NOTHING
ELSE UPDATE SET t=excluded.t;
END;

我收到一条错误消息

ERROR:  syntax error at or near "case"
LINE 3: do case t
           ^
WARNING:  there is no transaction in progress

我对收到一条错误消息并不感到惊讶,因为如果我在第一次尝试时就得到了即兴的陈述,这不会令人惊讶吗? ;-)

但是,应该可以执行此操作(只要语法正确),或者可以执行其他操作达到相同的效果。我知道如何进行冲突处理,冲突处理更新以及CASE / WHEN / ELSE。应该可以一起使用它们。

编辑:我将使用我尝试过但不起作用的版本进行更新

INSERT INTO test (mykey,t) VALUES (123,'a new value') 
ON CONFLICT ON CONSTRAINT test_constraint 
CASE t
WHEN excluded.t THEN DO NOTHING
ELSE DO UPDATE SET t=excluded.t;
END;

(相同错误)

1 个答案:

答案 0 :(得分:2)

您可以在WHERE子句中使用该条件。 IS DISTINCT FROM做空袭

INSERT INTO test (mykey,t) VALUES (123,'a new value') 
ON CONFLICT ON CONSTRAINT test_constraint 
 DO  UPDATE SET t = excluded.t 
   where test.t is distinct from excluded.t;

Demo