加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 如何获取upsert中冲突行的ID?

发布时间:2020-12-13 16:22:36 所属栏目:百科 来源:网络整理
导读:我有一个包含2列的表标记:id(uuid)和name(text).我现在想在表中插入一个新标签,但如果标签已经存在,我想简单地获取现有记录的id. 我以为我可以使用ON CONFLICT DO NOTHING和RETURNING“id”: INSERT INTO "tag" ("name")VALUES( 'foo' )ON CONFLICT DO NOT
我有一个包含2列的表标记:id(uuid)和name(text).我现在想在表中插入一个新标签,但如果标签已经存在,我想简单地获取现有记录的id.

我以为我可以使用ON CONFLICT DO NOTHING和RETURNING“id”:

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT DO NOTHING
RETURNING "id";

但是,如果名称为“foo”的标记已存在,则返回空结果集.

然后我更改了查询以使用noop DO UPDATE子句:

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT ("name") DO UPDATE SET "name" = 'foo'
RETURNING "id";

这按预期工作,但有点令人困惑,因为我只是将名称设置为已存在的值.

这是解决这个问题的方法还是我缺少一种更简单的方法?

这将在所有3种情况下工作(据我测试),如果要插入的值全部是新的或全部已经在表格或混合中:
WITH
  val (name) AS
    ( VALUES                          -- rows to be inserted
        ('foo'),('bar'),('zzz')
    ),ins AS
    ( INSERT INTO
        tag (name)
      SELECT name FROM val
      ON CONFLICT (name) DO NOTHING
      RETURNING id,name              -- only the inserted ones
    )
SELECT COALESCE(ins.id,tag.id) AS id,val.name
FROM val
  LEFT JOIN ins ON ins.name = val.name
  LEFT JOIN tag ON tag.name = val.name ;

可能还有其他一些方法可以做到这一点,也许不使用新的ON CONFLICT语法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读