SQL Server存储过程解析JSON需用NVARCHAR(MAX)参数并先ISJSON校验;JSON_VALUE仅提取标量值且路径须精确,中文键名需转义;多字段提取应优先用OPENJSON而非多次JSON_VALUE。

SQL Server 存储过程中能直接用 JSON_VALUE 解析入参,但前提是入参是合法 JSON 字符串且路径写对;否则返回 NULL 或报错,不是函数没生效,而是输入或路径错了。
存储过程参数必须声明为 NVARCHAR(MAX)
SQL Server 不支持原生 JSON 数据类型作为参数,只能用字符串承载。若误用 VARCHAR,中文键名、emoji 或带 Unicode 的值可能被截断或乱码:
-
NVARCHAR是必须的,JSON_VALUE内部按 Unicode 处理路径和内容 - 长度建议用
MAX,避免截断长 JSON(比如含 Base64 图片字段) - 不要用
TEXT或XML类型传参,它们不兼容 JSON 函数
JSON_VALUE 提取标量值时路径必须精确匹配
它只返回字符串、数字、布尔、null 这类单值;一旦路径指向对象或数组,结果就是 NULL,不会报错,容易误判成功:
- 正确:路径
'$.name'→ 返回'Alice'(字符串) - 错误:路径
'$'或'$.address'(address 是对象)→ 返回NULL,应改用JSON_QUERY - 中文键名要加双引号转义:路径写成
'$.["收货地址"]',不能写'$.收货地址' - 数组元素用方括号:提取第一个订单的金额 →
'$[0].amount'
必须先用 ISJSON() 校验再解析
用户传来的 JSON 可能格式错误(缺引号、逗号错位、控制字符),JSON_VALUE 遇到非法 JSON 会静默返回 NULL,而不是抛异常:
- 在存储过程开头加判断:
IF ISJSON(@json_param) = 0 BEGIN RAISERROR('Invalid JSON', 16, 1) RETURN END -
ISJSON()返回 1 才代表可安全解析,返回 0 或 NULL 都不可信 - 别依赖
TRY...CATCH捕获JSON_VALUE错误——它本身不抛异常
嵌套深、字段多时优先用 OPENJSON 而非连写多个 JSON_VALUE
当需要从同一段 JSON 中提取 5 个以上字段,或字段来自不同层级(如 $.user.name 和 $.order.items[0].price),硬写一堆 JSON_VALUE 不仅难读,性能也差:
-
OPENJSON(@json_param) WITH (name NVARCHAR(50) '$.user.name', price DECIMAL(10,2) '$.order.items[0].price')一次解析,结构清晰 -
OPENJSON自动处理 null 值映射,JSON_VALUE对缺失键也返回 NULL,但无法区分“键不存在”和“键值为 null” - 注意:
OPENJSON是行集函数,需搭配SELECT或INSERT INTO #temp使用,不能直接赋值给变量
最常被忽略的一点:SQL Server 的 JSON 函数全部基于字符串解析,没有缓存机制。如果同一段 JSON 在一个存储过程中被反复用 JSON_VALUE 提取十几次,实际做了十几次完整解析——这种场景应该先用 OPENJSON 一次性展开,再查临时表。


















