CodeGym /课程 /SQL SELF /jsonb_set()jsonb_insert()

jsonb_set()jsonb_insert() 更新 JSON 对象中的数据

SQL SELF
第 33 级 , 课程 4
可用

OK,PostgreSQL 里的 JSONB 是个超强的工具,能存很复杂的层级数据结构。但如果你想改一下 JSONB 列里的某个值,比如换个用户的手机号,或者往数组里加个新类别,咋办?听起来简单,但 JSONB 可不是表格,不能直接改某个单元格。要想在 JSON 对象里更新数据,我们得用点特殊函数。今天的主角就是:

  • jsonb_set():用来按“路径”修改或新增某个值。
  • jsonb_insert():用来往 JSON 数组里插入新元素。

jsonb_set() 更新数据

jsonb_set() 这个函数能让你改 JSONB 对象的一部分,或者往里加新 key 和 value。

基本语法

jsonb_set(target jsonb, path text[], new_value jsonb, create_missing boolean)
  • target — 你要更新的 JSONB 对象。
  • path — 字符串数组,表示你要改的 key 的路径。
  • new_value — 你想加进去或替换掉的值。
  • create_missing — 布尔参数(TRUE 或 FALSE),表示要不要自动创建缺失的 key。

来看个最简单的例子。假设我们有个 users 表,里面有个 profile 列,类型是 JSONB,存着用户的资料。有个用户要换手机号,怎么搞?

-- 创建表并插入数据
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    profile JSONB
);

INSERT INTO users (profile)
VALUES ('{"name": "奥托", "contact": {"phone": "+1-495-123-45-67"}}');

-- 更新手机号
UPDATE users
SET profile = jsonb_set(profile, '{contact,phone}', '"8-800-555-35-35"', FALSE)
WHERE id = 1;

-- 看看结果
SELECT profile FROM users WHERE id = 1;

结果:

{
  "name": "奥托",
  "contact": {
    "phone": "8-800-555-35-35"
  }
}

牛!手机号就这么改了!注意,key 的路径要用字符串数组写,比如 '{contact,phone}'

新增 key

如果你要改的 key 不存在,可以把 create_missing = TRUE,这样会自动帮你创建:

UPDATE users
SET profile = jsonb_set(profile, '{address,city}', '"柏林"', TRUE)
WHERE id = 1;

-- 看看结果
SELECT profile FROM users WHERE id = 1;

结果:

{
  "name": "奥托",
  "contact": {
    "phone": "8-800-555-35-35"
  },
  "address": {
    "city": "柏林"
  }
}

现在多了个地址部分,是不是很方便?

jsonb_insert() 插入数据

jsonb_insert() 这个函数用来往 JSONB 对象里的数组加新元素。

基本语法

jsonb_insert(target jsonb, path text[], new_value jsonb, insert_after boolean)
  • target — 目标 JSONB 对象。
  • path — 字符串数组,表示你想插入元素的数组路径。
  • new_value — 要加进去的值。
  • insert_after — 布尔参数。FALSE 表示插在指定索引前,TRUE 表示插在后面。

举个例子。假如我们有个表,profile 列里存着用户的兴趣列表。我们想往数组里加个新兴趣:

-- 先加点数据
UPDATE users
SET profile = jsonb_set(profile, '{interests}', '["运动", "音乐"]', TRUE)
WHERE id = 1;

-- 把新兴趣 "编程" 插到最前面
UPDATE users
SET profile = jsonb_insert(profile, '{interests,0}', '"编程"', FALSE)
WHERE id = 1;

-- 看看结果
SELECT profile FROM users WHERE id = 1;

结果:

{
  "name": "奥托",
  "contact": {
    "phone": "8-800-555-35-35"
  },
  "address": {
    "city": "柏林"
  },
  "interests": [
    "编程",
    "运动",
    "音乐"
  ]
}

常见问题和避坑指南

jsonb_set()jsonb_insert() 有点小 tricky,注意下面这些点:

  1. 路径写错。 如果路径不对,或者你想改的元素不存在但 create_missing=FALSE,要么报错,要么啥都不变。一定要先确认 JSON 结构。
  2. 数据类型不对。 new_value 必须是 JSONB 类型。如果你要插入字符串,记得用双引号包起来('"值"')。
  3. 数据被覆盖。 直接更新数组不用对的函数,可能会把原来的数据全覆盖。想安全加新元素,用 jsonb_insert()

错误示例:

-- 错误:路径不对
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新联系人"', FALSE)
WHERE id = 1;

这会报错,因为 profile 里没有 contacts 这个 key,而且 create_missing 是 FALSE。

怎么避免:

-- 设置 create_missing = TRUE
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新联系人"', TRUE)
WHERE id = 1;

实际应用场景

玩 JSONB 可不是闹着玩的,这可是很多现代应用的必备技能。举几个实际例子:

  • 存用户设置。 JSONB 超适合存那种每个用户都不一样的动态数据,比如 app 的个性化设置。
  • 对接外部 API。 拿 REST API 回来的原始 JSON 数据,直接丢 JSONB 里,超方便。
  • 大数据分析。 嵌套 JSON 结构很适合搞 IoT 数据、日志、分析啥的。

这就是我们关于 JSON 对象更新的入门讲解啦。现在你已经知道怎么往 JSONB 里插、改、加数据,还能避开常见的坑。下节课我们会讲怎么合并 JSONB 对象,让你玩得更溜!

1
调查/小测验
JSON数据处理第 33 级,课程 4
不可用
JSON数据处理
JSON数据处理
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION