可写 CTE 被认为是 9.5 之前的 UPSERT 解决方案,如插入中所述,关于 PostgreSQL 中的重复更新?
可以使用以下信息执行 UPSERT,无论它最终是 UPDATE 还是 INSERT,具有以下可写 CTE 习语:
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中所述-丢失更新
是否可以使用 PostgreSQL 9.5+ 新的“UPSERT”语法来实现类似的东西,受益于其优化并避免可能的约束违规?