如果值不在 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 中,则更改插入值的主要内容,如果未能解决你的问题,请参考以下文章

MySQL中的set和enum

插入该特定值更改的记录

MYSQL中 ENUM 类型的详细解释

如果 ID 在任何行中具有特定值,则更改值

如果属性值= [重复],则jquery更改类

如果类包含值,则更改背景颜色