使用INSERT ... ON CONFLICT DOHING RETURNING失败的行

问题描述 投票:1回答:2

假设我有下表:

CREATE TABLE tags (
    id int PK,
    name varchar(255),
    CONSTRAINT name_unique UNIQUE(name)
)

我需要一个查询,它将插入不存在的标记,并为所有请求的标记返回id。考虑以下:

INSERT INTO tags (name) values ('tag10'), ('tag6'), ('tag11') ON CONFLICT DO NOTHING returning id, name

此查询的输出是:

+---------------+
|  id   |  name |
|---------------|
|  208  | tag10 |
|---------------|
|  209  | tag11 |
+---------------+

我需要的是在输出中有tag6

postgresql postgresql-9.5
2个回答
6
投票

有点冗长,但我想不出别的:

with all_tags (name) as (
  values ('tag10'), ('tag6'), ('tag11')
), inserted (id, name) as (
   INSERT INTO tags (name)
   select name 
   from all_tags
   ON CONFLICT DO NOTHING 
   returning id, name
)
select t.id, t.name, 'already there'
from tags t
  join all_tags at on at.name = t.name
union all
select id, name, 'inserted'
from inserted;

来自tags的外部选择可以看到表格的快照,就像插入新标签之前一样。带常量的第三列仅用于测试查询,以便可以识别插入的行和不插入的行。


1
投票

有了这个表:

CREATE TABLE tags (
    id serial PRIMARY KEY,
    name text UNIQUE
);

只要查询中的值是唯一的,解决方法就是:

INSERT INTO tags (name) 
VALUES ('tag10'), ('tag6'), ('tag11') 
ON CONFLICT DO UPDATE name = EXCLUDED.name RETURNING id, name;
© www.soinside.com 2019 - 2024. All rights reserved.