【问题标题】:How to Retrieve id of inserted row when using upsert with WITH cluase in Posgres 9.5?在 Postgres 9.5 中使用带有 WITH 子句的 upsert 时如何检索插入行的 id?
【发布时间】:2016-12-25 03:32:57
【问题描述】:

我正在尝试使用“WITH”在 Postgres 9.5 中进行不安查询

with s as (
            select id
            from products
            where product_key = 'test123'
        ), i as (
            insert into products (product_key, count_parts)
            select 'test123', 33
            where not exists (select 1 from s)
            returning id                       
        )
        update products
        set product_key='test123', count_parts=33
        where id = (select id from s) 
        returning id

显然,我只在更新时检索 id,即使我知道插入成功,也没有在插入时得到任何结果。

我需要修改此查询,以便在插入和更新时都能获取 id。

谢谢!

【问题讨论】:

标签: sql postgresql postgresql-9.5


【解决方案1】:

我不清楚你为什么在 WITH first SELECT 时这样做,但你只返回 UPDATE id 的原因是因为你没有选择 INSERT return。

如 cmets 中所述(和链接),Postgres 9.5 支持 INSERT ON CONFLICT 子句,这是一种更简洁的使用方式。

还有一些9.5前后的例子:

9.5之前:WITH常用方式

WITH    u AS (
            UPDATE      products
            SET         product_key='test123', count_parts=33
            WHERE       product_key = 'test123'
            RETURNING   id
        ),i AS (
            INSERT
            INTO        products ( product_key, count_parts )
            SELECT      'test123', 33
            WHERE       NOT EXISTS( SELECT 1 FROM u )
            RETURNING   id
        )
SELECT  *
FROM    (       SELECT id FROM u
        UNION   SELECT id FROM i
        ) r;

9.5 之后:使用 INSERT .. ON CONFLICT

INSERT INTO products ( product_key, count_parts )
VALUES      ( 'test123', 33 )
ON CONFLICT ( product_key ) DO
UPDATE
SET         product_key='test123', count_parts=33
RETURNING   id;

更新:

正如评论中所暗示的,使用INSERT .. ON CONFLICT 方式可能会有轻微的缺点。
如果表使用自动增量并且这个查询经常发生,那么WITH 可能是一个更好的选择。
查看更多:https://stackoverflow.com/a/39000072/1161463

【讨论】:

  • 在9.5中,如果使用INSERT ... ON CONFLICT UPDATE,表格上的自增主键会出现逐渐变大的空隙。如果您的表以 9.5 方式执行大量 UPSERT,这可能会导致您很快超出增量值的范围。不幸的是,WITH 似乎是目前唯一的解决方案。 stackoverflow.com/a/39000072/1161463
  • @eComEvo:这很有趣,很高兴知道 - 感谢您的提示。在这种情况下,我同意,继续使用WITH
  • 请记住 WITH 解决方案容易受到竞争条件的影响。
猜你喜欢
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2016-03-13
  • 2011-09-08
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多