json_remove仅按指定路径删除节点,不校验内容、不报错、不支持条件过滤;路径错误或不存在时静默忽略,误用将导致意外删减。

直接结论:JSON_REMOVE 能安全删除指定路径节点,但“安全”取决于路径是否精确、是否存在、是否误删兄弟节点——它不支持条件过滤,只认路径。
JSON_REMOVE 只按路径硬删,不查内容
它不是 DELETE WHERE,不会扫描 JSON 内容找匹配的值。给一个路径,它就删那个位置;路径不存在,语句照常执行但无效果(不报错);路径写错,可能删掉意料之外的字段。
-
JSON_REMOVE('{"a":1,"b":2}','$.c')→ 原样返回{"a":1,"b":2}(静默忽略) -
JSON_REMOVE('{"a":1,"b":2}','$.a')→ 返回{"b":2} -
JSON_REMOVE('{"user":{"name":"matta","id":100}}','$.user.name')→ 只删name,留下{"user":{"id":100}}
删数组里某个对象?先得定位到索引,不能靠值匹配
比如 JSON 字段存的是用户列表:[{"kullanici":"matta","rutbe":"20"},{"kullanici":"Linuxy","rutbe":"19"}],想删 kullanici = "matta" 的整条对象——JSON_REMOVE 本身做不到。
- 它没有类似
WHERE kullanici = "matta"的能力 - 你必须提前知道该对象在数组里的索引(比如是第 0 个),才能写
'$[0]' - 如果顺序不确定,或要批量删多个匹配项,得先用
JSON_CONTAINS+JSON_EXTRACT在应用层查出索引,再拼 SQL;或改用 PHP/Python 解析后过滤重写
嵌套深、路径含点号或中括号?必须用双反斜杠转义
MySQL 路径语法里 . 和 [ 是特殊字符。如果键名本身就含这些(比如 "user.name" 或 "items[0]"),不转义就会解析失败或删错位置。
- 错误写法:
JSON_REMOVE(json_col, '$.user.name')→ 会被当成user对象下的name字段 - 正确写法:
JSON_REMOVE(json_col, '$."user.name"')或JSON_REMOVE(json_col, '$."items[0]"') - 实操建议:所有非常规键名都用双引号包裹路径段,避免歧义
UPDATE 时别漏 WHERE 条件,否则全表 JSON 都被清空
常见翻车操作:UPDATE users SET data = JSON_REMOVE(data, '$.temp') 没加 WHERE,结果所有行的 temp 键都被删了——包括那些本来就没这个键的行(虽无害,但多余)。
- 更危险的是删数组元素:
UPDATE orders SET items = JSON_REMOVE(items, '$[0]')会把每单第一个商品都干掉 - 务必搭配明确条件,例如:
WHERE id = 123或WHERE JSON_CONTAINS(data, '"draft"', '$.status') - 上线前先用
SELECT id, JSON_EXTRACT(data, '$.xxx') FROM ... WHERE ...预查目标数据,确认路径有效
真正容易被忽略的点是:JSON_REMOVE 不验证路径指向的是否为可删目标——删对象键可以,删数组索引可以,但删一个本应是字符串的值(比如 '$.price')也成功,只是返回 null;删一个不存在的数组索引(如 '$[999]')也静默跳过。它的“安全”来自不崩,而非不误删。











