sql server 2022 中 json 字段不支持原生 dml,所有增删改查均依赖字符串级函数:更新用 json_modify(需 lax 模式删键、append 增数组),查询用 json_value/json_query,解析用 openjson(配合 with 显式结构);高频查询须建 persisted 计算列+索引,操作前必校验 isjson,路径含特殊字符需双引号,输入类型必须为 nvarchar(max)。

直接上结论:SQL Server 2022 中不能对 JSON 字段“原地增删改查”,必须用 JSON_MODIFY 做更新、OPENJSON 拆解后插入/删除、JSON_VALUE 提取查询——它没有 JSON 类型的 DML 语法,所有操作都基于字符串解析与重组。
怎么用存储过程更新 JSON 字段里的某个值
核心是 JSON_MODIFY,它只接受 NVARCHAR 输入,返回 NVARCHAR,不改变原始结构,但会把非标量值(如对象或数组)转成字符串再塞进去,容易踩坑。
- 必须先确认字段是 NVARCHAR 类型,不是 VARCHAR;否则中文乱码、解析失败
- 路径写错(比如写成
'$.user.name'但实际是'$.data.user.name')时,JSON_MODIFY默认静默失败,返回原 JSON,不会报错 - 想删一个键?用
JSON_MODIFY(@json, 'lax $.field', NULL),注意必须加lax前缀,strict 模式下 NULL 会被当字面量保留 - 追加数组元素?
JSON_MODIFY(@json, 'append $.tags', 'newtag'),但只能 append 到最外层数组;嵌套数组得先JSON_QUERY提出来再拼 - 别在循环里反复调用
JSON_MODIFY做批量更新——每次都是全量字符串重组,CPU 和内存开销陡增;一次性构造好新 JSON 再 UPDATE
怎么从 JSON 数组插入多条记录到关系表
别手写 WHILE + JSON_VALUE 模拟循环,这是最常见也最慢的写法。正确姿势是让 OPENJSON 一次性展开,交给 SQL 引擎做集合操作。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 输入 JSON 是数组(如
N'[{"id":1,"val":"a"},{"id":2,"val":"b"}]'),直接OPENJSON(@json),不用路径参数 - 输入 JSON 是对象包数组(如
N'{"items":[{"id":1}...]}'),必须指定路径:OPENJSON(@json, '$.items') -
WITH子句里声明列类型要严丝合缝:比如id INT '$.id',若 JSON 里"id": "1"(字符串),不加CAST就是 NULL - 字段缺失不报错,对应列为 NULL;想过滤掉缺字段的行,得在 WHERE 里显式判断,比如
WHERE id IS NOT NULL - 如果要 INSERT 多张表(比如主表+明细表),先用
OPENJSON展开到临时表或 CTE,再分别 JOIN 插入,避免重复解析
怎么安全地在 WHERE 条件里查 JSON 字段
JSON_VALUE 在 WHERE 里裸用等于自毁性能——没索引时每次都要全表解析 JSON 字符串,数据一过万就卡死。
- 高频查询字段(如
$.order_id)必须建计算列:ALTER TABLE Orders ADD order_id AS JSON_VALUE(data, '$.order_id') - 然后在计算列上建索引:
CREATE INDEX IX_Orders_order_id ON Orders(order_id),注意计算列必须是 PERSISTED 才能索引 - WHERE 中用
WHERE JSON_VALUE(data, '$.status') = 'shipped'只适用于低频或小表;大数据量必须走计算列+索引 - 查数组是否包含某值?
JSON_VALUE不行,得用OPENJSON展开后EXISTS或IN,或者等 SQL Server 2025 的JSON_CONTAINS(当前预览版) - 路径含特殊字符(如
$.user-name)必须用双引号括起来:'$."user-name"',否则解析失败返回 NULL
为什么存储过程里处理 JSON 容易出错
根本原因是 JSON 解析行为高度依赖输入格式、路径合法性、类型匹配,而这些在 T-SQL 里没有编译期检查,全是运行时报错或静默失败。
- 没做
ISJSON(@input) = 1校验就直接传给OPENJSON,遇到非法 JSON 会直接报错中断执行 - 把
JSON_VALUE当JSON_QUERY用:前者只取标量,后者取子对象/数组;误用导致 NULL 或截断 - 忽略编码:输入 JSON 是 UTF-8 字节流但存成 NVARCHAR,SQL Server 会按 UCS-2 解码,可能丢字符或出
- 兼容性级别低于 130(SQL Server 2016)时,所有 JSON 函数不可用;2022 默认是 160,但旧库迁移后可能仍是 140 或更低,务必查
SELECT compatibility_level FROM sys.databases - 存储过程参数传入 JSON 时,必须声明为
NVARCHAR(MAX),用VARCHAR或固定长度会截断










