【问题标题】:Postgres: Using ON CONFLICT together with CASEPostgres:将 ON CONFLICT 与 CASE 一起使用
【发布时间】:2019-03-16 11:17:34
【问题描述】:

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

我有一张桌子(忽略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

我收到一条错误消息并不感到惊讶,因为如果我在第一次尝试时就得到了即兴陈述,那不是很神奇吗? ;-)

但是,应该可以执行此操作(只要语法正确),或者其他具有相同效果的操作。我知道如何在 ON CONFLICT DO NOTHING、ON CONFLICT DO UPDATE 和 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;

(同样的错误)

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    您可以在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

    【讨论】:

    • 这行得通,谢谢。 +1 用于正确处理 NULL 案例。
    猜你喜欢
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 2014-03-18
    • 2016-04-26
    相关资源
    最近更新 更多