JSON_VALUE只能提取标量值,返回NULL的三大原因:ISJSON校验失败、路径未以$开头或不指向标量、SQL Server不支持方括号索引;中文键名需用N''前缀,数值布尔值须显式转换,数组或对象应改用OPENJSON。

JSON_VALUE 只能取标量值,嵌套对象或数组一律返回 NULL —— 这不是 bug,是设计限制。
为什么 JSON_VALUE 总是返回 NULL
它不报错,只静默返回 NULL,容易误判为“数据为空”。必须立刻检查三点:
-
ISJSON(json_col)必须为 1;若字段定义是VARCHAR(200)却存了 500 字节 JSON,或含 HTML 实体(如"),ISJSON就是 0 - 路径必须以
$开头、严格大小写匹配、用点号分隔、数组索引从 0 开始;写成'$.User.name'(首字母大写)或'$.user["name"]'(带方括号)都会返回 NULL - 目标路径必须指向标量:即字符串、数字、布尔或 null;
'$.items'是数组,'$.address'是对象,调用JSON_VALUE必然返回 NULL
中文键名和嵌套路径怎么写
中文键名完全支持,但路径字符串必须用 N'' 前缀声明 Unicode,否则可能乱码或匹配失败:
SELECT JSON_VALUE(PersonInfo, N'$.姓名') AS 姓名, JSON_VALUE(PersonInfo, N'$.地址.城市') AS 城市, JSON_VALUE(PersonInfo, N'$.地址.邮政编码') AS 邮政编码 FROM PersonData;
注意:'$.地址.城市' 是合法路径,'$.地址["城市"]' 不合法(SQL Server 不支持方括号索引字符串键);深层嵌套无特殊语法,逐级点号即可。
数值和布尔类型怎么安全使用
JSON_VALUE 默认返回 NVARCHAR(4000),哪怕原始 JSON 里是 199.99 或 true。裸用会导致隐式转换失败或逻辑错误:
- 参与比较或计算前必须显式转换:
CAST(JSON_VALUE(data, '$.price') AS DECIMAL(18,2)) - 布尔值要转为
BIT:CAST(JSON_VALUE(data, '$.active') AS BIT),否则'true'字符串在 WHERE 中当条件会恒为真 - 空值传播必须兜底:
ISNULL(CAST(JSON_VALUE(data, '$.count') AS INT), 0),否则整行计算可能变 NULL
什么时候该换 OPENJSON 而不是硬扛 JSON_VALUE
遇到以下任一情况,说明你已超出 JSON_VALUE 的能力边界,该切到 OPENJSON:
- 要展开数组成多行(如
'$.orders.items'有多个元素,想查出每项sku和qty) - 需要遍历不确定长度的数组(
'$.tags[*]'写法在 SQL Server 2019 不被支持) - 路径动态变化,或需对同一 JSON 解析出结构+标量混合结果(比如既要
$.id字符串,又要$.items数组内容)
最常被忽略的一点:即使只是取 '$.items[0].sku',只要业务上存在 items 为空数组或缺失的可能,JSON_VALUE 就返回 NULL —— 而 OPENJSON 配合 WITH 子句可统一处理缺失、空、非法等所有情况,容错性高得多。


















