加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

插入,在重复更新在PostgreSQL?

发布时间:2020-12-13 16:57:56 所属栏目:百科 来源:网络整理
导读:几个月前,我从Stack Overflow的答案学习了如何使用以下语法在MySQL中同时执行多个更新: INSERT INTO table (id,field,field2) VALUES (1,A,X),(2,B,Y),(3,C,Z)ON DUPLICATE KEY UPDATE field=VALUES(Col1),field2=VALUES(Col2); 我现在切换到PostgreSQL,
几个月前,我从Stack Overflow的答案学习了如何使用以下语法在MySQL中同时执行多个更新:
INSERT INTO table (id,field,field2) VALUES (1,A,X),(2,B,Y),(3,C,Z)
ON DUPLICATE KEY UPDATE field=VALUES(Col1),field2=VALUES(Col2);

我现在切换到PostgreSQL,显然这是不正确的。它指的是所有正确的表,所以我认为这是一个问题使用不同的关键字,但我不知道在PostgreSQL文档中包括这里。

为了澄清,我想插入几个东西,如果他们已经存在更新他们。

PostgreSQL从9.5版本开始有 UPSERT语法,带有 ON CONFLICT子句。与以下语法(类似于MySQL)
INSERT INTO the_table (id,column_1,column_2) 
VALUES (1,'A','X'),'B','Y'),'C','Z')
ON CONFLICT (id) DO UPDATE 
  SET column_1 = excluded.column_1,column_2 = excluded.column_2;

搜索postgresql的电子邮件组归档“upsert”导致找到an example of doing what you possibly want to do,in the manual:

Example 38-2. Exceptions with UPDATE/INSERT

This example uses exception handling to perform either UPDATE or INSERT,as appropriate:

CREATE TABLE db (a INT PRIMARY KEY,b TEXT);

CREATE FUNCTION merge_db(key INT,data TEXT) RETURNS VOID AS
$$
BEGIN
    LOOP
        -- first try to update the key
        -- note that "a" must be unique
        UPDATE db SET b = data WHERE a = key;
        IF found THEN
            RETURN;
        END IF;
        -- not there,so try to insert the key
        -- if someone else inserts the same key concurrently,-- we could get a unique-key failure
        BEGIN
            INSERT INTO db(a,b) VALUES (key,data);
            RETURN;
        EXCEPTION WHEN unique_violation THEN
            -- do nothing,and loop to try the UPDATE again
        END;
    END LOOP;
END;
$$
LANGUAGE plpgsql;

SELECT merge_db(1,'david');
SELECT merge_db(1,'dennis');

可能有一个例子,如何做到这一点批量,使用CTE在9.1及以上,在hackers mailing list:

WITH foos AS (SELECT (UNNEST(%foo[])).*)
updated as (UPDATE foo SET foo.a = foos.a ... RETURNING foo.id)
INSERT INTO foo SELECT foos.* FROM foos LEFT JOIN updated USING(id)
WHERE updated.id IS NULL;

更清晰的例子见a_horse_with_no_name’s answer。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读