我有一个包含2列的表标记:id(uuid)和name(text).我现在想在表中插入一个新标签,但如果标签已经存在,我想简单地获取现有记录的id.
我以为我可以使用ON CONFLICT DO NOTHING和RETURNING“id”:
INSERT INTO "tag" ("name") VALUES( 'foo' ) ON CONFLICT DO NOTHING RETURNING "id";
然后我更改了查询以使用noop DO UPDATE子句:
INSERT INTO "tag" ("name") VALUES( 'foo' ) ON CONFLICT ("name") DO UPDATE SET "name" = 'foo' RETURNING "id";
这按预期工作,但有点令人困惑,因为我只是将名称设置为已存在的值.
这将在所有3种情况下工作(据我测试),如果要插入的值全部是新的或全部已经在表格或混合中:
原文链接:https://www.f2er.com/postgresql/192371.htmlWITH 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语法.