【问题标题】:Change insert value if value is not in ENUM如果值不在 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'

如何在插入时使用条件插入或更新值?

【问题讨论】:

    标签: java sql postgresql jdbc sql-insert


    【解决方案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) 是可能的。(?)
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2016-01-14
    • 2018-10-20
    • 2012-06-07
    • 2023-03-30
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    相关资源
    最近更新 更多