我正在使用 PostgreSQL v9.6.6。我正在运行以下 SQL:
insert into t_vs_config_key (name, description, is_brand_dependent)
values ('ucp.cluster','UCP Cluster', true)
ON CONFLICT (name) DO UPDATE SET is_brand_dependent=true;
这会导致以下错误,因为 name
列没有被索引为唯一的。我无法添加索引,因为存在不唯一的现有数据。
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
问题 有什么想法如何在没有索引的情况下执行 upsert 语句?
谢谢
最佳答案
正如评论中已经提到的,没有唯一索引就不能使用ON CONFLICT
。
但是,您可以通过向表中添加一个新列来指示行是否有效并根据该标志创建部分唯一索引来确保 future 的插入是唯一的:
alter t_vs_config_key
add column valid boolean not null default false;
这会将所有现有行初始化为 valid = false
现在对于 future 的行,将此列的默认值更改为 true
alter table t_vs_config_key
alter column valid set default true;
并通过添加检查约束确保不再可以插入“无效”行:
alter table t_vs_config_key
add constraint check_valid check (valid);
现在您可以创建唯一索引:
create unique index on t_vs_config_key(name)
where valid;
可用于 on conflict
子句:
insert into t_vs_config_key (name, description, is_brand_dependent)
values ('ucp.cluster','UCP Cluster', true)
ON CONFLICT (name) where valid DO UPDATE
SET is_brand_dependent = true;
注意语句中的 where valid
子句。
关于SQL Upsert 语句不适用于非索引列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52185331/