【问题标题】:How do I update a JSON field in PostgreSQL?如何更新 PostgreSQL 中的 JSON 字段?
【发布时间】:2020-05-15 18:43:32
【问题描述】:

我有一个表,其中包含一个名为 data 的列,其中包含一些 JSON。如果表中任何给定行的 data 列不为空,则它将包含一个 JSON 编码的对象,其键名为 companyDescription。与 companyDescription 关联的值是任意 JavaScript 对象。

如果我这样查询我的表

select data->>'companyDescription' from companies where data is not null;

我得到这样的行

{"ops":[{"insert":"\n"}]}

我正在尝试更新表中的所有行,以便 companyDescription 值将以下列方式包装在另一个 JSON 编码的 JavaScript 对象中:

{"type":"quill","content":{"ops":[{"insert":"\n"}]}}

这是我尝试过的,但我认为它不起作用,因为->> 运算符用于选择一些 JSON 字段作为 text,并且确实失败并出现语法错误。

update companies
set data->>'companyDescription' = CONCAT(
  '{"type":"quill","content":',
  (select data->>'companyDescription' from companies),
  '}'
);

这样做的正确方法是什么?

【问题讨论】:

    标签: sql json postgresql


    【解决方案1】:

    您可以使用函数jsonb_set。目前XMLJSON 值是不可变的。您不能更新这些值的某些部分。您可以用一些新的修改值替换这些值。

    postgres=# select * from test;
    ┌──────────────────────────────────────────────────────────────────────┐
    │                                  v                                   │
    ╞══════════════════════════════════════════════════════════════════════╡
    │ {"companyId": 10, "companyDescription": {"ops": [{"insert": "\n"}]}} │
    └──────────────────────────────────────────────────────────────────────┘
    (1 row)
    
    postgres=# select jsonb_build_object('type', 'quill', 'content', v->'companyDescription') from test;
    ┌───────────────────────────────────────────────────────────┐
    │                    jsonb_build_object                     │
    ╞═══════════════════════════════════════════════════════════╡
    │ {"type": "quill", "content": {"ops": [{"insert": "\n"}]}} │
    └───────────────────────────────────────────────────────────┘
    (1 row)
    
    postgres=# select jsonb_set(v, ARRAY['companyDescription'], jsonb_build_object('type', 'quill', 'content', v->'companyDescription')) from test;
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                             jsonb_set                                              │
    ╞════════════════════════════════════════════════════════════════════════════════════════════════════╡
    │ {"companyId": 10, "companyDescription": {"type": "quill", "content": {"ops": [{"insert": "\n"}]}}} │
    └────────────────────────────────────────────────────────────────────────────────────────────────────┘
    (1 row)
    

    所以你的最终陈述可能看起来像:

    update companies
      set data = jsonb_set(data::jsonb, 
                           ARRAY['companyDescription'], 
                           jsonb_build_object('type', 'quill', 
                                              'content', data->'companyDescription'))
      where data is not null;
    

    【讨论】:

    • 谢谢;这就解释了为什么我之前的所有搜索结果都显示jsonb 中的示例而不是json。如何在您的示例中获得v?我正在尝试使用我的原始选择,但我不确定如何将每一行映射到自身。我需要使用某种循环吗?这是我正在尝试的:ix.io/2m5u
    • @JezenThomas - v 是列名,它是 data。我会修复这个查询
    • 太好了,谢谢。这确实有效;只需要明确的data::JSONB 类型转换。
    猜你喜欢
    • 2021-02-28
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多