如何在PostgreSQL中更新JSON字段?

如何在PostgreSQL中更新JSON字段?,sql,json,postgresql,Sql,Json,Postgresql,我有一个表,其中有一个名为data的列,其中包含一些JSON。如果表中任何给定行的data列不为空,则它将包含一个JSON编码的对象,其键名为companyDescription。与companyDescription关联的值是任意JavaScript对象 如果我像这样查询我的表 select data->>'companyDescription' from companies where data is not null; {"ops":[{"insert":"\n"}]} 我

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

如果我像这样查询我的表

select data->>'companyDescription' from companies where data is not null;
{"ops":[{"insert":"\n"}]}
我有这样的争吵

select data->>'companyDescription' from companies where data is not null;
{"ops":[{"insert":"\n"}]}
我正在尝试更新表中的所有行,以便将
companyDescription
值以以下方式包装到另一个JSON编码的JavaScript对象中:

{"type":"quill","content":{"ops":[{"insert":"\n"}]}}
这是我尝试过的,但我认为它不会起作用,因为
->
操作符用于选择一些JSON字段作为文本,并且确实由于语法错误而失败

update companies
set data->>'companyDescription' = CONCAT(
  '{"type":"quill","content":',
  (select data->>'companyDescription' from companies),
  '}'
);
正确的方法是什么?

您可以使用函数。当前
XML
JSON
值是不可变的。无法更新这些值的某些部分。可以用一些新的修改值替换这些值

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
?我试图使用我原来的select,但我不确定如何将每一行映射到它自己。我需要使用某种循环吗?以下是我正在尝试的:@JezenThomas-
v
是列名,它是
数据
。我会把这个问题解决得很好,谢谢。这确实有效;只需要显式的
data::JSONB
typecast。