我正在尝试对具有部分唯一索引的表进行upsert操作
create table test (
p text not null,
q text,
r text,
txt text,
unique(p,q,r)
);
create unique index test_p_idx on test(p) where q is null and r is null;
create unique index test_pq_idx on test(p, q) where r IS NULL;
create unique index test_pr_idx on test(p, r) where q is NULL;
简单来说,p
不是 null,并且只有 q
或 r
中的一个可以为 null。
重复插入会如预期般引发约束违规。
insert into test(p,q,r,txt) values ('p',null,null,'a'); -- violates test_p_idx
insert into test(p,q,r,txt) values ('p','q',null,'b'); -- violates test_pq_idx
insert into test(p,q,r,txt) values ('p',null, 'r','c'); -- violates test_pr_idx
然而,当我尝试对upsert使用唯一约束时。
insert into test as u (p,q,r,txt) values ('p',null,'r','d')
on conflict (p, q, r) do update
set txt = excluded.txt
尽管如此,它仍然会抛出约束违规的错误。
错误:重复键违反唯一约束 "test_pr_idx" 详细信息:(p, r)=(p, r) 已经存在。
但是我希望 on conflict
子句能够捕获并执行更新操作。
我做错了什么?我应该使用 index_predicate
吗?
index_predicate 用于允许推断部分唯一索引。满足谓词条件的任何索引(实际上不需要是部分索引)都可以被推断。遵循 CREATE INDEX 格式。 https://www.postgresql.org/docs/9.5/static/sql-insert.html