json_array_append 会自动将非数组值转为单元素数组再追加,路径不存在时静默忽略,多路径对串行计算而非并行,且需显式赋值才生效。

直接说结论: JSON_ARRAY_APPEND 不是“往数组里加元素”那么简单——它会自动把非数组值转成单元素数组再追加,且路径不存在时静默忽略,不是报错也不是创建。用错路径或没理解“左到右逐对计算”逻辑,结果常和预期差很远。
路径必须指向数组,否则行为会意外转换类型
如果 path 指向的是字符串、数字或对象(比如 $.name 是一个字符串 "Alice"),JSON_ARRAY_APPEND 会先把那个值包进一个数组,再把新值追加进去。
- 执行
JSON_ARRAY_APPEND('{"name":"Alice"}', '$.name', 'Bob'),结果是{"name": ["Alice", "Bob"]},不是报错,也不是覆盖 - 执行
JSON_ARRAY_APPEND('{"score":95}', '$.score', 5),结果是{"score": [95, 5]} - 但如果目标路径是
$.hobbies,而原 JSON 中根本没有hobbies字段,这一对 path-value 就会被完全忽略,不报错也不创建
多个 path-value 对是串行计算,不是并行叠加
你传入 JSON_ARRAY_APPEND(json_doc, '$[0]', 'x', '$[1]', 'y'),不是“同时操作两个位置”,而是先用第一对修改 json_doc,再用第二对操作上一步的结果。
- 假设
@j = '["a", "b"]',执行JSON_ARRAY_APPEND(@j, '$[0]', 'x', '$[1]', 'y'):- 第一步:对
$[0](即"a")追加'x'→ 变成["a", "x"],整个文档变成["a", "x", "b"](注意:原数组被扩展了) - 第二步:再对新文档的
$[1](即"x")追加'y'→ 把"x"变成["x", "y"],最终是["a", ["x", "y"], "b"]
- 第一步:对
- 所以别指望它像数组批量 push 那样“一次加多个同级元素”;要加多个同路径元素,得重复写同一路径,如
'$.hobbies','val1','$.hobbies','val2'
UPDATE 场景中容易漏掉 SET 赋值,导致看似没生效
MySQL 的函数不会就地修改字段,JSON_ARRAY_APPEND(data, '$.hobbies', 'swimming') 只返回新 JSON,不改变 data 值本身。
- 错误写法:
UPDATE users SET JSON_ARRAY_APPEND(data, '$.hobbies', 'swimming') WHERE id = 1;—— 这条语句语法合法但没更新任何字段 - 正确写法:
UPDATE users SET data = JSON_ARRAY_APPEND(data, '$.hobbies', 'swimming') WHERE id = 1; - 如果要加多个值,仍需显式赋值:
UPDATE users SET data = JSON_ARRAY_APPEND(data, '$.hobbies', 'cooking', '$.hobbies', 'gardening') WHERE id = 1;
NULL 和非法 JSON 会直接中断,但路径错误不报错
这是调试时最易混淆的一点:输入为 NULL 或文档格式非法(如带中文引号、多余逗号),函数立刻返回 NULL;但路径写错(比如 $.tags 实际是 $.skills),函数只是跳过该对,继续处理后面的 path-value。
- 检查是否真失败,先用
SELECT JSON_VALID(data), JSON_TYPE(data) FROM users WHERE id = 1;确认字段内容合法 - 用
SELECT JSON_EXTRACT(data, '$.hobbies') FROM users WHERE id = 1;看路径是否存在、类型是否为ARRAY - 别依赖“没报错=成功”——静默忽略路径是设计行为,不是 bug
真正麻烦的从来不是语法写不对,而是你以为它在 append,其实它在 autowrap + replace + ignore 的组合拳里悄悄改了结构。动手前,先 SELECT 出原始值和单步 JSON_ARRAY_APPEND 结果对比,比查文档更快定位问题。











