如果值不在 ENUM 中,则更改插入值
Posted
技术标签:
【中文标题】如果值不在 ENUM 中,则更改插入值【英文标题】:Change insert value if value is not in ENUM 【发布时间】:2020-03-12 23:19:05 【问题描述】:我想向 Postgres 插入值
如果我在表中有枚举类型并且我想更改输入值不在列表中 枚举
喜欢
create type us_state as enum ('AL', ..., 'NULL');
insert into user (name, state)
values ('Bob', 'AA')
conflict on state is not valid us_state update value = 'NULL'
如何在插入时使用条件插入或更新值?
【问题讨论】:
【参考方案1】:就目前而言,on conflict
不识别枚举违规。 INSERT
documentation 说:
可选的
ON CONFLICT
子句指定引发唯一违规或排除约束违规错误的替代操作。
不幸的是,枚举类型不属于该类别(同样适用于检查约束,否则这里可能是一种解决方案)。
我们可以使用enum_range()
列出枚举值的技巧,然后在条件表达式中使用它:
insert into users(name, state)
select
name,
case when state = any(enum_range(null::us_state)::name[])
then state::us_state
end
from (values ('Bob', 'AA')) t(name, state)
请注意,当枚举中不存在给定值时,这会生成NULL
值,而不是'NULL'
等任意字符串;这在我看来是表示不匹配值的正确方法。
Demo on DB Fiddle:
create type us_state as enum ('AL', 'WA');
create table users(name text, state us_state);
-- an attempt with "on conflict"
insert into users (name, state) values ('Bob', 'AA') on conflict(state) do nothing
-- ERROR: invalid input value for enum us_state: "AA";
-- LINE 1: insert into users (name, state) values ('Bob', 'AA') on conf...
-- new query
insert into users(name, state)
select
name,
case when state = any(enum_range(null::us_state)::name[])
then state::us_state
end
from (values ('Bob', 'AA'), ('Bill', 'AL')) t(name, state);
-- 2 rows affected
select * from users;
姓名 |状态
:--- | :----
鲍勃 | 空
比尔 |铝
【讨论】:
不错的“技巧”:) (enum_range
!) ..对于“最大的灵活性”(null vs 'null'),查询coalesce( pg_type join pg_enum)
是可能的。(?)以上是关于如果值不在 ENUM 中,则更改插入值的主要内容,如果未能解决你的问题,请参考以下文章