【问题标题】:How to update a jsonb column's field in PostgreSQL?如何更新 PostgreSQL 中的 jsonb 列字段?
【发布时间】:2015-07-16 10:55:13
【问题描述】:

所以我想试试 PostgreSQL 的jsonb。在我的表中,我有一个名为 extras 的列,属于 jsonb 类型。

extras 中的样本数据看起来像 {"param1": 10, "param2": 15}

我想只使用 sql 语句修改 JSON。我想做这样的事情:

如果extrasparam2 的值超过12,则更新extrasparam1 字段,将其值加10。

如何编写这样的 SQL 语句?我知道我可以在应用层轻松做到这一点,但我想在 SQL 层本身做到这一点,因为我可能要处理的行数会很大,我不想在 db-application- 上浪费时间数据库往返

【问题讨论】:

标签: postgresql postgresql-9.4 jsonb


【解决方案1】:

这应该在 PostgreSQL 9.5 中完成:

create table t (extras jsonb);
insert into t values
    ('{"param1": 10, "param2": 15}'),
    ('{"param1": 10, "param2": 5}');

UPDATE t 
  SET extras = jsonb_set(extras, '{param1}', ((extras->>'param1')::real + 10)::text::jsonb) 
  WHERE (extras#>>'{param2}')::real > 12;

select * from t;
            extras            
------------------------------
 {"param1": 10, "param2": 5}
 {"param1": 20, "param2": 15}
(2 rows)

【讨论】:

    【解决方案2】:

    jsonb 类型用于存储整个文档。如果您更改文档的任何部分,则需要为该列分配一个新值。因为 Postgres 将旧版本保留一段时间,这是一项昂贵的操作。

    考虑到这一点,下面是一个如何不更新 jsonb 列的示例:

    create table t1 (doc jsonb);
    
    insert into t1 values 
        ('{"param1": 10, "param2": 15}'),
        ('{"param1": 10, "param2": 5}');
    
    update  t1
    set     doc = ('{"param1": ' ||
            ((doc->'param1')::text::int + 10)::text ||
            ', "param2": ' ||
            (doc->'param2')::text ||
            '}')::jsonb
    where   (doc->'param2')::text::int > 12;
    
    select * from t1;
    

    打印出来:

                doc
    ------------------------------
     {"param1": 10, "param2": 5}
     {"param1": 20, "param2": 15}
    (2 rows)
    

    【讨论】:

    • 我试过你的方法。 IMO的表现相当糟糕。比我用 mongodb + 应用层做的更糟糕。我不会在我的应用程序中使用它,除非 jsonb 拥有比上述方法更好的修改技术。无论如何,感谢您的回答。
    • 使用字符串连接修改jsonb 似乎是一个非常糟糕的主意。此外,在当前的 PostgreSQL 版本中,可以使用 ->> 运算符,无需强制转换为 text
    猜你喜欢
    • 2021-02-12
    • 1970-01-01
    • 2021-06-07
    • 2019-04-24
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多