应直接使用openjson而非自定义函数;其默认返回key、value、type三列,with子句可映射强类型结构;注意json_value仅取标量、json_query取对象/数组;兼容级别须≥130,存储用nvarchar(max)。

直接用 OPENJSON,别写自定义函数——SQL Server 2016+ 原生支持已足够可靠,性能远超 CLR 或 T-SQL 手动解析。
OPENJSON 默认行为返回三列:key、value、type
不带 WITH 子句时,OPENJSON 把 JSON 对象每个属性或数组每个元素展开成一行,固定返回三列:
-
key:对象中字段名,或数组中索引(字符串形式,如"0"、"1") -
value:该字段/元素的值(始终为nvarchar(max)) -
type:值类型编号(0=string,1=int,2=real,3=bool,4=array,5=object,6=null)
常见错误:直接 SELECT * FROM OPENJSON(@json) 后想用 WHERE value = 25 ——会失败,因为 value 是字符串,需显式转换,比如 CAST(value AS int)。
用 WITH 子句定义结构化输出
这才是生产环境正确用法:OPENJSON 配合 WITH 能把嵌套 JSON 映射成强类型列,避免手动 JSON_VALUE 拼接。
关键点:
-
WITH中路径以$开头,$.skills[0]表示数组首项,$.address.city表示嵌套对象字段 - 列类型必须明确指定,如
name nvarchar(50) '$.name';若 JSON 中该字段为null,对应列值也为null(不报错) - 数组需用
OPENJSON(json_col, '$.array_path')显式指定路径,再在WITH中映射子项
示例:解析 { "id": 1, "name": "Alice", "tags": ["dev", "sql"] }
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
SELECT id, name, tag FROM OPENJSON(@json) WITH ( id int '$.id', name nvarchar(50) '$.name' ) AS hdr CROSS APPLY OPENJSON(@json, '$.tags') WITH (tag nvarchar(20) '$') AS tags;
JSON_VALUE 和 JSON_QUERY 的分工要清楚
JSON_VALUE 提取标量值(string/int/bool),JSON_QUERY 提取子对象或数组(保持 JSON 结构)——混用会导致意外截断或类型错误。
典型陷阱:
- 对数组字段误用
JSON_VALUE:如JSON_VALUE(@json, '$.skills')返回null,因为 skills 是数组,不是标量;必须用JSON_QUERY - 对深层嵌套对象漏掉中间层级:如
JSON_VALUE(@json, '$.user.profile.age')在profile为null时直接返回null,不会报错,但可能掩盖数据缺失问题 -
JSON_QUERY返回结果仍是nvarchar(max),不能直接参与数值计算,需先用OPENJSON展开
兼容性级别和存储格式容易被忽略
OPENJSON 和所有 JSON 函数要求数据库兼容性级别 ≥ 130(即 SQL Server 2016+)。哪怕你连的是 SQL Server 2025,如果数据库是从旧版本升级而来且未手动升级兼容级别,JSON 功能仍不可用。
检查方式:SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME();
升级命令:ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 150;(根据实际版本选 130/140/150/160/170)
另外,JSON 数据仍建议存为 nvarchar(max),SQL Server 2025 新增的 json 类型目前仅限 Azure SQL 和预览版,本地 SQL Server 2019/2022 不支持,强行使用会报错 Invalid data type 'json'。










