PostgreSQL ON CONFLICT,具有多列唯一约束名称

时间:2018-09-27 18:10:07

标签: sql postgresql upsert

在尝试对PostgreSQL进行UPSERT时,我遇到了一种我不了解的行为。这些文档似乎表明INSERT语句的冲突目标可以是索引表达式约束名称。但是,当尝试引用约束名称时,出现“列...不存在”错误。

我的第一个尝试是仅创建一个UNIQUE索引,该索引在约束推断下可以很好地工作:

create table kv (key text, value text, extra text);
create unique index kv_key_value on kv(key, value);
insert into kv (key, value) values ('k1', 'v1');
-- this works:
insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (key, value) do update set extra=excluded.extra;

-- this does not
insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (kv_key_value) do update set extra=excluded.extra;

在上面的表格中,我在“索引:”下看到以下内容:

"kv_key_value" UNIQUE, btree (key, value)

我的第二个尝试是将唯一性约束明确地放置在创建表中:

create table kv (
  key text,
  value text,
  extra text,
  constraint kv_key_value unique(key, value));

在上表中,“索引:”的输出略有不同(上例中的“ UNIQUE CONSTRAINT”与“ UNIQUE”):

"kv_key_value" UNIQUE CONSTRAINT, btree (key, value)

但是我仍然无法将约束名称指定为冲突目标:

insert into kv (key, value, extra) values ('k1', 'v1', 'e1')
  on conflict (kv_key_value) do update set extra=excluded.extra;
ERROR:  column "kv_key_value" does not exist
LINE 2:       on conflict (kv_key_value) do update set extra=exclude...

我在这里误会了什么吗?我完全明白可以使用等效表达式并依靠约束推断,但是我想知道为什么当文档听起来像是应该约束名称时,约束名称似乎不起作用?

1 个答案:

答案 0 :(得分:3)

语法错误。

对于约束,应为:

INSERT INTO kv (key, value, extra)
   VALUES ('k1', 'v1', 'e1')
   ON CONFLICT ON CONSTRAINT kv_key_value
      DO UPDATE SET extra = excluded.extra;
相关问题