可写CTE被认为是9.5之前UPSERT的解决方案,如Insert, on duplicate update in PostgreSQL?所述
可以使用以下可写CTEs惯用语执行UPSERT,其中包含的信息是作为更新还是插入结束的:
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"语法,从优化中获益,避免可能的约束冲突,可以实现类似的功能吗?