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语法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
