【问题标题】:Postgres 9.4.7 INSERT INTO without ON CONFLICT [duplicate]Postgres 9.4.7 INSERT INTO 没有冲突 [重复]
【发布时间】:2018-06-29 06:57:01
【问题描述】:

我真的很想写一个这样的查询:

INSERT INTO test_table (id, dt, amt)
VALUES(4, current_timestamp, 15)
ON CONFLICT (id)
DO UPDATE
    SET dt = VALUES(dt)
        amt = VALUES(amt)

问题是,我使用的 Postgres 版本 (9.4.7) 不支持 ON CONFLICT 构造。关于如何在不升级 Postgres 的情况下实现这一目标的任何想法?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    如果你经常这样做。你可以编写一个函数来为你做这件事。 您可以通过两种方式进行。

    1. 先检查,然后插入或更新。
    
        CREATE OR REPLACE FUNCTION insert_test_table(int, timestamp, varchar)
        RETURNS int AS
        $BODY$
        BEGIN
            IF (EXISTS(SELECT id FROM test_table WHERE id = $1)) THEN
                UPDATE test_table SET dt = $2, amt = $3 WHERE id = $1;
                RETURN 2;
            ELSE
                INSERT INTO test_table (id, dt, amt) VALUES($1, $2, $3);
                RETURN 1;
            END IF;
            RETURN 0;
            END;
        $BODY$
        LANGUAGE plpgsql;
    
    1. 使用例外:
    
        CREATE OR REPLACE FUNCTION insert_test_table(int, timestamp, varchar)
        RETURNS int AS
        $BODY$
        BEGIN
            INSERT INTO test_table (id, dt, amt) VALUES($1, $2, $3);
            RETURN 1;
            EXCEPTION WHEN unique_violation THEN 
                    BEGIN
                        UPDATE test_table SET dt = $2, amt = $3 WHERE id = $1;  
                        RETURN 2
                    END;
        END;
        $BODY$
        LANGUAGE plpgsql;
    

    第二种方式可能与其他唯一约束冲突,所以要小心。

    【讨论】:

    • 两种解决方案都不完全正确,因为它们受制于竞争条件。请参阅 PostgreSQL wiki 以获取解决方案。
    • 对不起,我没看清楚。如果您不介意,可以帮我解释一下吗?
    • 我指的是the documentation 中的示例。该表可能会在第一条和第二条 SQL 语句之间发生变化。
    【解决方案2】:

    PostgreSQL 9.4 没有任何内置的 UPSERT(或 MERGE)工具,在并发使用的情况下有效地做到这一点非常困难。

    This article discusses the problem in useful detail.

    一般来说,您必须在两个选项之间进行选择:

    • 重试循环中的单独插入/更新操作;或
    • 锁定表并进行批量合并

    如需完整解决方案,请阅读此内容 SO Answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2012-07-27
      相关资源
      最近更新 更多