sql - 如何更新 PostgreSQL 中的 JSON 字段?
问题描述
我有一个表,其中有一列名为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),
'}'
);
这样做的正确方法是什么?
解决方案
你可以使用一个函数jsonb_set
。当前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;
推荐阅读
- r - 从R中的日期提取工作日数
- c++ - 为什么 `std::ostream& operator<<` 覆盖必须在 C++ 的“全局”范围内声明?
- redis - 如何使用 redis-cli cluster create 创建 redis 自定义主从节点
- sparql - 为什么我有空结果 SPARQL 查询?
- python-3.x - Kivy on_release,创建一个新的Tab
- qliksense - 通过 Qlik sense web 连接器连接到 Google 表格
- java - git gc 似乎覆盖了一个包文件,使打开的文件描述符持有对“old-xxx.pack”的引用
- sql-server - 更改同一数据库中超过 3 个表中存在的相同 COLUMN 数据类型
- java - 从 TestRunner 运行时出现 NullPointerException,当我从功能文件单独运行时同样有效
- go - 在 Redis 中按值过滤(使用 go 和 redis-go)