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

前端之家收集整理的这篇文章主要介绍了如何确定upsert是否是PostgreSQL 9.5 UPSERT的更新?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
可写CTE被认为是9.5000之前的UPSERT解决方案,如 Insert,on duplicate update in 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-lost-updates所述的约束违规操作失败

可以使用Postgresql 9.5新的“UPSERT”语法实现类似的功能,从优化中获益,并避免可能的约束违规?

@lad2025’s answer年起,结果可以通过将 settingscustomized optionsrelated functions在WHERE子句中滥用来获得所需的副作用.
CREATE TABLE t(id INT PRIMARY KEY,v TEXT);

INSERT INTO t (id,v)
    SELECT $1,$2
    WHERE 'inserted' = set_config('upsert.action','inserted',true)
    ON CONFLICT (id) DO UPDATE
        SET v = EXCLUDED.v
        WHERE 'updated' = set_config('upsert.action','updated',true)
RETURNING current_setting('upsert.action') AS "upsert.action";

set_config的第三个参数是is_local:true表示在事务结束时设置将消失.更确切地说,current_setting(‘upsert.action’)将返回NULL(而不是抛出一个错误)直到会话结束.

猜你在找的Postgre SQL相关文章