最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何解析MySQL存储过程中的JSON参数
时间:2026-08-12 09:48:49 编辑:袖梨 来源:一聚教程网
JSON_EXTRACT返回NULL的三大原因是路径错误、值为空或字段本身为NULL;应先用JSON_VALID校验,再用->>脱壳提取,并结合JSON_CONTAINS_PATH判断键是否存在。
JSON_EXTRACT 返回 NULL 怎么办
不是函数坏了,是路径错、值空、字段本身为 NULL,三者都静默返回 NULL,且不报错。存储过程里一旦把 NULL 赋给 DECLARE 的非 NULL 变量,或参与 IF v_age > 18 这类判断,逻辑就“失效”了。
- 先用
JSON_VALID(in_json)确认入参是合法 JSON,否则后续全白忙 - 路径必须严格匹配:写成
'$.user.name'但实际结构是'$.profile.name'→ 返回NULL - 提取裸值必须用
->>或JSON_UNQUOTE(JSON_EXTRACT(...));只写JSON_EXTRACT(...)得到的是带引号的字符串(如"张三"),后续= '张三'永远为假 - 数组越界(如
'$[5]'但数组只有 3 个元素)也返回NULL,不会中断执行
怎么安全提取 JSON 中的数字或字符串字段
别信隐式转换——JSON_EXTRACT(in_json, '$.age') > 18 在存储过程中结果不可靠,常为 0 或 NULL。必须先脱壳,再比较。
- 字符串字段:用
in_json->>'$.name',得到纯字符串张三,可直接用于=、LIKE或拼接 - 数字字段:同样用
in_json->>'$.age',得到可参与算术运算的整数,不是 JSON 类型的25 -
JSON_UNQUOTE(NULL)仍返回NULL,安全,可放心用于所有路径提取 - 如果字段可能缺失,先用
JSON_CONTAINS_PATH(in_json, 'one', '$.email')判断 key 是否存在,再决定是否提取
更新 JSON 字段时为什么 JSON_SET 不可靠
JSON_SET 在存储过程中有三个隐性风险:字段为 NULL 时结果仍是 NULL;路径不存在时强行新增键;并发写入无锁保护。多数业务场景下,应该优先用 JSON_REPLACE。
- 仅修改已有 key:用
JSON_REPLACE(in_json, '$.status', 'done'),路径不存在则原样返回,不污染结构 - 需要新增或覆盖且确认容错:才考虑
JSON_SET,但建议加IF JSON_CONTAINS_PATH(...)前置判断 - 原子递增(如计数器):写成
JSON_SET(json_col, '$.count', COALESCE(json_col->>'$.count', 0) + 1),避免先查后改的竞态 - 字段本身为
NULL时,JSON_REPLACE(NULL, '$.x', 1)返回NULL,务必在调用前用IF json_col IS NOT NULL THEN ...
遍历 JSON 数组只能靠 WHILE 循环
MySQL 存储过程没有 FOR EACH 或 JSON_TABLE(除非你确定是 MySQL 8.0.4+),唯一可靠方式是手写循环。错一步索引就取到 NULL,还查不出原因。
- 用
JSON_LENGTH(json_array)获取长度,注意它返回元素个数,不是最大索引 - 循环变量
i从0开始,上限设为JSON_LENGTH(json_array) - 1(别写成) - 动态拼路径:
JSON_EXTRACT(json_array, CONCAT('$[', i, ']')),每次都要拼 - 提取后建议用
JSON_TYPE(item)判断类型,防止把对象当字符串处理引发隐式转换错误 - 低版本(MySQL 5.7)不支持
JSON_TABLE(),硬用会报错FUNCTION JSON_TABLE does not exist
真正容易被忽略的是:所有 JSON 提取操作都依赖路径精确性和类型一致性,而这两点在存储过程中没有任何运行时提示。写完必须用真实数据测一遍 NULL、空数组、错路径、多层嵌套越界这四种边界情况,否则上线后逻辑“看起来正常”,实则部分分支永远不走。