最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SQL存储过程中如何解析并处理JSON格式的参数输入
时间:2026-06-30 09:37:58 编辑:袖梨 来源:一聚教程网
必须用 NVARCHAR(MAX) 声明 JSON 参数并先调 ISJSON() 校验,否则 JSON_VALUE 和 OPENJSON 会静默返回 NULL;JSON_VALUE 仅取标量且路径须正确转义,多字段或嵌套结构应优先用 OPENJSON WITH;对象/数组必须用 JSON_QUERY 提取。
必须用 NVARCHAR(MAX) 声明参数,且解析前一定要调 ISJSON() 校验——漏掉任一环节,JSON_VALUE 和 OPENJSON 都会静默返回 NULL,而不是报错。
参数声明必须是 NVARCHAR(MAX)
SQL Server 没有原生 JSON 类型,所有 JSON 都得靠字符串承载。用 VARCHAR 会导致中文键名(如 "收货地址")、emoji 或 Base64 字段乱码或截断;用 TEXT 或 XML 类型则直接不兼容 JSON 函数。
路径和内容内部按 Unicode 解析,NVARCHAR 是强制要求。
长度不能写 NVARCHAR(4000) ——哪怕你“确定”不会超长,实际运行中含图片 Base64 的 JSON 很容易踩坑。
- 正确:
@json_param NVARCHAR(MAX) - 错误:
@json_param VARCHAR(8000)、@json_param TEXT、@json_param NVARCHAR(4000)
JSON_VALUE 只能取标量,路径写错或类型不匹配就返回 NULL
它只接受指向字符串、数字、布尔或 null 的路径;一旦路径指向对象(如 $.address)或数组(如 $.tags),结果就是 NULL,不是函数失效,而是语义不匹配。
中文键名必须转义:'$.["收货地址"]',不能写 '$.收货地址'。
数组元素用方括号:'$[0].amount' 提取第一个订单金额。
返回值默认是 NVARCHAR(4000),字段可能超长时要显式转换:CAST(JSON_VALUE(@json, '$.desc') AS NVARCHAR(MAX))。
- 安全用法:
JSON_VALUE(@json, '$.name')→ 返回字符串 - 危险用法:
JSON_VALUE(@json, '$.address')→ 若address是对象,返回NULL,别误以为“字段为空” - 别在
WHERE里裸用:WHERE JSON_VALUE(data, '$.status') = 'done'——没索引时每次全表解析 JSON,性能崩得快
多字段或嵌套结构优先用 OPENJSON + WITH 子句
从同一段 JSON 提取 3 个以上字段,或字段跨不同层级(如 $.user.name 和 $.order.items[0].price),硬写一堆 JSON_VALUE 不仅难维护,CPU 开销也高。OPENJSON 必须配 WITH 才能映射成可用列;不带 WITH 只返回 key/value/type 三列,全是字符串,没法直接用于业务逻辑。
路径必须以 $ 开头:'$.user.name' 对,'user.name' 静默失败。
嵌套数组要用 CROSS APPLY 分层展开:先 OPENJSON(@json, '$.orders'),再对每行 CROSS APPLY OPENJSON(value, '$.items')。
- 正确:
OPENJSON(@json) WITH (name NVARCHAR(50) '$.user.name', price DECIMAL(10,2) '$.order.items[0].price') - 错误:
OPENJSON(@json)不加WITH,或WITH里写'user.name'(缺$) - 调试技巧:临时加
ERROR ON ERROR到关键JSON_VALUE路径里,比如JSON_VALUE(@json, '$.user.profile.phone' ERROR ON ERROR),一错立刻中断
别把 JSON_QUERY 当 JSON_VALUE 用
如果 JSON 里某个字段是对象或数组(比如 "tags": ["a","b"]),用 JSON_VALUE 提取会返回 NULL;必须用 JSON_QUERY 保留原始结构。JSON_VALUE(@j, '$.tags') → NULLJSON_QUERY(@j, '$.tags') → ["a","b"](原样字符串,无额外引号)
拼接进新 JSON 时尤其要注意:CONCAT('{ "list": ', JSON_QUERY(@j, '$.tags'), ' }') 安全;误用 JSON_VALUE 会导致变成 "list": "["a","b"]",前端 JSON.parse() 直接报错。
- 标量值(字符串/数字/布尔)→ 用
JSON_VALUE - 对象或数组 → 必须用
JSON_QUERY - 复杂点在于嵌套层级越深,
CROSS APPLY链越长,容易漏掉某一层的OPENJSON展开