SQL Server 2019 处理 JSON 必须声明 NVARCHAR(MAX) 参数并用 ISJSON() 校验;JSON_VALUE 仅取标量且路径需转义中文、显式转换长字段;多字段优先用 OPENJSON WITH;兼容级别不低于130;无解析缓存,需手动暂存复用。

SQL Server 2019 中处理 JSON 输入,核心就两件事:参数声明必须是 NVARCHAR(MAX),解析前必须用 ISJSON() 校验——漏掉任一环节,后续所有 JSON_VALUE 或 OPENJSON 都可能静默返回 NULL 而不报错,导致业务逻辑误判。
存储过程参数必须声明为 NVARCHAR(MAX)
SQL Server 没有原生 JSON 类型,所有 JSON 都以字符串承载。若误用 VARCHAR,中文键名(如 "收货地址")、emoji 或 Base64 字段会乱码或截断;用 TEXT 或 XML 则直接不兼容 JSON 函数。
-
NVARCHAR是强制要求,因为 JSON 函数内部按 Unicode 解析路径和内容 - 长度必须用
MAX,避免长 JSON(如含图片 Base64)被截断 - 不要写成
NVARCHAR(4000)——哪怕你“确定”不会超长,实际运行中极易踩坑
JSON_VALUE 只能取标量值,路径写错或类型不匹配就返回 NULL
它只接受指向字符串、数字、布尔或 null 的路径;一旦指向对象或数组(比如 '$.address' 是个对象),结果就是 NULL,不是函数失效,而是语义不匹配。
- 中文键名必须转义:
'$.["收货地址"]',不能写'$.收货地址' - 数组元素用方括号:
'$[0].amount'提取第一个订单金额 - 返回值默认是
NVARCHAR(4000),若字段可能超长,显式转:CAST(JSON_VALUE(@json, '$.desc') AS NVARCHAR(MAX)) - 别在
WHERE里裸用JSON_VALUE做等值查询——没索引时每次都要全表解析 JSON,性能极差
多字段或嵌套结构优先用 OPENJSON + WITH 子句
从同一段 JSON 提取 3 个以上字段,或字段跨不同层级(如 $.user.name 和 $.order.items[0].price),硬写一堆 JSON_VALUE 不仅难维护,CPU 开销也高。
-
OPENJSON必须配WITH才能映射成可用列;不带WITH只返回key/value/type三列,全是字符串,无法直接用于业务逻辑 -
WITH中路径必须以$开头,例如'$.user.name',写成'user.name'会静默失败 - 嵌套数组需分层
CROSS APPLY:先OPENJSON(@json, '$.orders'),再对每行CROSS APPLY OPENJSON(value, '$.items') - 调试时可临时加
ERROR ON ERROR到JSON_VALUE路径里快速暴露路径错误(OPENJSON本身不支持该语法,但配合JSON_VALUE抽关键字段验证很有效)
兼容性级别低于 130 会导致 OPENJSON 不可用
SQL Server 2019 默认兼容级别通常是 150,但若数据库是从旧版本升级而来,可能仍是 120 或更低——此时调用 OPENJSON 会直接报“找不到对象”,不是语法错,而是功能不可用。
- 查当前级别:
SELECT name, compatibility_level FROM sys.databases WHERE name = DB_NAME() - 最低要求是 130(SQL Server 2016 引入
OPENJSON);若不能改级,只能退回到多次JSON_VALUE+ 手动拼接逻辑 - 注意:
JSON_QUERY和JSON_MODIFY也受同样限制,不是所有 JSON 函数都向下兼容
最常被忽略的其实是缓存缺失:SQL Server 的 JSON 函数纯字符串解析,无任何中间结果缓存。同一段 JSON 在一个存储过程中被反复解析,等于反复做全文扫描——别指望“解析一次,复用多次”,必须一次性展开后存进临时表或表变量再复用。

















