【问题标题】:postgres jsonb_set multiple keys updatepostgres jsonb_set 多键更新
【发布时间】:2016-12-17 10:01:36
【问题描述】:

我有带有 jsonb 列的数据库表。

number  | data
    1   | {"name": "firstName", "city": "toronto", "province": "ON"}

我需要一种更新数据列的方法。 所以我的输出应该是这样的:

{"name": "firstName", "city": "ottawa", "province": "ON", "phone": "phonenum", "prefix": "prefixedName"}

json_set 可以吗? 我添加了如下查询:

update table_name set data = jsonb_set(data, '{city}', '"ottawa"') where number = 1;

但是,我需要一种方法来添加新的键值(如果它不存在)并更新键值(如果存在)。是否有可能在单个查询中实现这一点?

【问题讨论】:

    标签: postgresql jsonb


    【解决方案1】:

    documentation says:

    ||运算符连接其每个操作数顶层的元素。 ... 例如,如果两个操作数都是具有共同键字段名称的对象,则结果中字段的值将只是右侧操作数的值

    所以使用您的示例数据:

    update table_name set
        data = data || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}'
        where number = 1;
    

    此外,如果您要编辑的对象不在顶层 - 只需将串联和 jsonb_set 函数结合起来。例如,如果原始数据看起来像

    {"location": {"name": "firstName", "city": "toronto", "province": "ON"}}
    

    然后

    ...
    data = jsonb_set(
        data, 
        '{location}', data->'location' || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}')
    ...
    

    【讨论】:

    • 太棒了,这很有魅力。谢谢!我还不能投票,因为我没有足够的分数,但肯定会竖起大拇指。
    • @MarcoPrins 您是否尝试过阅读 Oracle 文档?与之相比,PostgreSQL 文档是文学杰作:o)
    • 有时当你得到错误:未知签名:jsonb_set(jsonb,string,jsonb)它是由于类型转换。添加 ::TEXT[] 如下所示解决了我的问题... data = jsonb_set(data, '{location}' ::TEXT[] , data->'location' || '{"city": "渥太华”,“电话”:“电话号码”,“前缀”:“前缀名称”}' ::jsonb)...
    • 如果您要从查询中的动态数据中填充更新的字段和/或更新多个字段,则会提供有用的提示。您可以使用json_build_object 创建更新对象。例如:data->'location' || jsonb_build_object('city', "cityColName", 'phonenum', "phoneCalName")。这比@Paarth 下面建议的尝试动态创建 jsonb 字符串要容易得多。
    • 我无法使用 JPA Query 更新多个 jsonb 列字段,有什么帮助吗?
    【解决方案2】:

    你可以试试这个

    这里我们使用jsonb连接运算符||连接两个jsonb对象

    update table_name set data = (select val from (
    (select 
    CASE WHEN data ? key THEN jsonb_set(data, '{' || key || '}', quote_nullable(updated_value))
    ELSE 
    data || ('{' || quote_ident(key) || ':' || quote_ident(some_value) || '}')::jsonb
    END val
     from json_each_text((select data::json from tbl))
    CROSS JOIN tbl t
    where key in ('city','phone','prefix') and number=1)) where number=1
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2020-02-27
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多