gpt4 book ai didi

postgresql - 如何确定 upsert 是否是 PostgreSQL 9.5+ UPSERT 的更新?

转载 作者:行者123 更新时间:2023-11-29 12:25:50 29 4
gpt4 key购买 nike

可写 CTE 被认为是 9.5 之前的 UPSERT 解决方案,如 Insert, on duplicate update in PostgreSQL? 中所述

可以使用以下可写 CTE 惯用法的信息执行 UPSERT,无论它最终是 UPDATE 还是 INSERT:

WITH
update_cte AS (
UPDATE t SET v = $1 WHERE id = $2 RETURNING 'updated'::text status
),
insert_cte AS (
INSERT INTO t(id, v) SELECT $2, $1 WHERE NOT EXISTS
(SELECT 1 FROM update_cte) RETURNING 'inserted'::text status
)
(SELECT status FROM update_cte) UNION (SELECT status FROM insert_cte)

此查询将返回“已更新”或“已插入”,或者可能(很少)因违反约束而失败,如 https://dba.stackexchange.com/questions/78510/why-is-cte-open-to-lost-updates 中所述

是否可以使用 PostgreSQL 9.5+ 新的“UPSERT”语法实现类似的东西,从其优化中获益并避免可能的约束冲突?

最佳答案

我相信 xmax::text::int > 0 是最简单的技巧:

so=# DROP TABLE IF EXISTS tab;
NOTICE: table "tab" does not exist, skipping
DROP TABLE
so=# CREATE TABLE tab(id INT PRIMARY KEY, col text);
CREATE TABLE
so=# INSERT INTO tab(id, col) VALUES (1,'a'), (2, 'b');
INSERT 0 2
so=# INSERT INTO tab(id, col)
VALUES (3, 'c'), (4, 'd'), (1,'aaaa')
ON CONFLICT (id) DO UPDATE SET col = EXCLUDED.col
returning *,case when xmax::text::int > 0 then 'updated' else 'inserted' end,ctid;
id | col | case | ctid
----+------+----------+-------
3 | c | inserted | (0,3)
4 | d | inserted | (0,4)
1 | aaaa | updated | (0,5)
(3 rows)

INSERT 0 3
so=# INSERT INTO tab(id, col)
VALUES (3, 'c'), (4, 'd'), (1,'aaaa')
ON CONFLICT (id) DO UPDATE SET col = EXCLUDED.col
returning *,case when xmax::text::int > 0 then 'updated' else 'inserted' end,ctid;
id | col | case | ctid
----+------+---------+-------
3 | c | updated | (0,6)
4 | d | updated | (0,7)
1 | aaaa | updated | (0,8)
(3 rows)

INSERT 0 3

关于postgresql - 如何确定 upsert 是否是 PostgreSQL 9.5+ UPSERT 的更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37781925/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com