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

前端之家收集整理的这篇文章主要介绍了postgresql – 如何获取upsert中冲突行的ID?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个包含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语法.

猜你在找的Postgre SQL相关文章