json_extract返回null主因是路径错误或数据不合法:需以$开头,普通key不加引号(如$.name),特殊字符key必须双引号(如$."first-name"),数组用方括号且下标从0开始,源字段须为合法json。

JSON_EXTRACT 返回 NULL 不报错,但结果不对
这是最常被误判为“报错”的情况:语句能执行,JSON_EXTRACT() 却安静地返回 NULL。根本原因通常是路径写错或数据不合法。
排查顺序建议:
- 先用
JSON_VALID(col)确认字段值真是 JSON,不是带花括号的字符串(比如'{"name": "张三"}'是合法的,{name: "张三"}或"{...}"套了双引号就非法) - 再用
JSON_KEYS(col)看顶层键名,确认结构是否和你写的路径匹配(注意大小写、空格、下划线) - 对嵌套对象中含短横线、数字开头、保留字的 key,必须用双引号包裹路径段,例如:
'$.user."first-name"'、'$.data."2024"、'$.user."order"' - 数组访问必须用方括号且下标从 0 开始:
'$.items[0].price',写成'$.items.0.price'会静默失败
升级后突然报语法错误:ERROR 1064 或 FUNCTION does not exist
MySQL 5.7+ 原生支持 JSON_EXTRACT,但升级后仍报错,常见于两类场景:
- 数据库版本实际低于 5.7(比如从 5.6 升级失败,
SELECT VERSION()确认真实版本) - 用户库中存在旧版视图/存储过程,其定义里硬编码了非标准 JSON 表达式,升级后元数据未刷新;此时
mysql_upgrade不处理这些对象,需手动DROP+CREATE视图 - 极少数情况是字符集残留问题:表或列仍是
utf8(非utf8mb4),导致 emoji 或某些生僻字在解析时触发校验失败,可临时用CONVERT(col USING utf8mb4)包裹再传入JSON_EXTRACT
提取后字段显示乱码或变成二进制 blob
JSON_EXTRACT() 返回的是 JSON 类型,不是字符串——这是升级后最易忽略的语义变化。直接 SELECT 它,客户端可能渲染为 0x7B226E616D65223A2022E5BCA0E4B889227D 这类十六进制。
- 要转成可读字符串,必须套一层
JSON_UNQUOTE():JSON_UNQUOTE(JSON_EXTRACT(data, '$.name')) - 如果字段本身是
TEXT或VARCHAR类型但存了 JSON 字符串,升级后 MySQL 可能拒绝隐式转换,此时需显式CAST(data AS JSON)再传入JSON_EXTRACT - 连接层编码也得对齐:执行
SET NAMES utf8mb4,避免客户端解码错位
数组长度计算错误或取不到元素
用 LENGTH(JSON_EXTRACT(arr, '$[0]')) 算数组首项长度?别这么做。它返回的是 JSON 字符串的字节长度,不是数组元素个数。
- 查数组长度请用
JSON_ARRAY_LENGTH(col),它专为 JSON 数组设计,返回整数 - 取数组所有元素需配合
JSON_TABLE()(MySQL 8.0.4+)或循环生成序号(低版本可用numbers辅助表) - 路径中数组索引越界(如
'$[99]'而实际只有 3 个元素)不会报错,只返回NULL,务必结合IFNULL()或COALESCE()做兜底
JSON_EXTRACT() 当字符串截取工具来用——这些细节一漏,调试时就得来回比对十几行日志。











