JSON_SET

功能概述

按 JSONPath 修改 JSON 值:路径已存在时替换原值,路径不存在但父节点存在时插入新值,返回修改后的 JSON。一次调用可以传入多组路径和值,适合在

UPDATE
UPDATE
或查询中直接改写 JSON 列的部分字段,而不用把整个 JSON 拆开再重新拼接。

只需删除字段时用 JSON_REMOVE;需要从零构造 JSON 时用 JSON_OBJECT。

语法

JSON_SET(<json>, <path1>, <value1> [, <path2>, <value2> ...])

参数说明

  • <json>
    <json>
    :JSON 类型,要修改的 JSON 值。字符串需先用 PARSE_JSON 转换。为 NULL 时返回 NULL。

  • <path>
    <path>
    :STRING 类型,目标位置的 JSONPath,如
    $.a
    $.a
    、
    $.a.b
    $.a.b
    、
    $.arr[1]
    $.arr[1]
    、
    $
    $
    (整个 JSON)。

  • <value>
    <value>
    :要写入的值。可以是数值、字符串、布尔等标量,也可以是 JSON 值(如
    JSON_OBJECT(...)
    JSON_OBJECT(...)
    、
    PARSE_JSON(...)
    PARSE_JSON(...)
    ),写入时转换为对应的 JSON 类型。

路径的处理规则:

  • 路径已存在:替换为新值。路径为
    $
    $
    时替换整个 JSON。
  • 路径不存在、父节点是对象:在父对象中新增该 key。
  • 数组下标超出范围:把值追加到数组末尾,不会补齐中间位置。
  • 父节点不存在(如对
    {}
    {}
    设置
    $.a.b
    $.a.b
    ):不做任何修改,也不报错。
  • 多组路径和值按从左到右的顺序依次生效,后一组看到的是前一组修改后的结果。

使用示例

替换已有字段、修改数组元素、新增嵌套对象:

SELECT json_set( parse_json('{"a":[1,2],"b":{"c":3}}'), '$.b', 2, '$.a[1]', 9, '$.root', json_object('x', true));

{"a":[1,9],"b":2,"root":{"x":true}}

$.b
$.b
原来是对象,被整体替换为
2
2
;
$.a[1]
$.a[1]
把数组第 2 个元素改为
9
9
;
$.root
$.root
不存在,作为新 key 插入。

多组路径依次生效。先创建

$.a
$.a
,后面的路径才能写入
$.a.b
$.a.b
;同一路径设置两次,以最后一次为准:

SELECT json_set( parse_json('{}'), '$.a', json_object(), '$.a.b', 1, '$.a.b', 2);

{"a":{"b":2}}

父节点不存在时不做修改:

SELECT json_set(parse_json('{}'), '$.a.b', 1);

{}

数组下标超出范围时追加到末尾:

SELECT json_set(parse_json('[1]'), '$[8]', 2);

[1,2]

批量更新表中 JSON 列的字段。前置数据:

CREATE TABLE IF NOT EXISTS doc_json_set_users (id INT, profile JSON); INSERT INTO doc_json_set_users VALUES (1, parse_json('{"name":"张三","level":"regular"}')), (2, parse_json('{"name":"李四","level":"regular","tags":["new"]}'));

把用户 1 升级为 VIP,并记录升级日期:

UPDATE doc_json_set_users SET profile = json_set(profile, '$.level', 'vip', '$.upgrade_date', '2024-06-01') WHERE id = 1; SELECT id, profile FROM doc_json_set_users ORDER BY id;

idprofile
1{"level":"vip","name":"张三","upgrade_date":"2024-06-01"}
2{"level":"regular","name":"李四","tags":["new"]}

注意事项

  • 参数个数必须是奇数且至少 3 个:一个 JSON 后跟一组或多组路径和值。
  • <path>
    <path>
    只能是字符串常量,不支持通配符。
  • 父节点不存在时静默跳过,不会自动创建中间层级。需要多层新建时,先用一组路径写入外层对象(见上方示例)。
  • <json>
    <json>
    为 NULL 时返回 NULL。

相关文档

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询