能,但必须严格匹配路径语义、类型规则和转义逻辑;路径决定增删改操作类型,数组/对象需JSON_QUERY包裹,类型需显式转换,JSON_MODIFY每次返回新字符串且无并发控制。

能,但必须严格匹配路径语义、类型规则和转义逻辑,否则看似更新成功,实际写进去的是带双引号的字符串或整个字段被覆盖。
JSON_MODIFY 路径写法决定是「改值」「增键」还是「删键」
路径不是随便拼的字符串,它直接控制操作类型:
-
$.name:更新name字段的值(若存在);若不存在且为lax模式(默认),则插入新键;strict模式下直接报错The given path does not match a field in the JSON text -
append $.tags:必须带append前缀,且$.tags必须指向一个数组——否则静默失败或报错 -
$.skills[0]:只能更新已有索引位置的元素;$.skills[99]在lax下不报错但也不生效,在strict下明确报错 -
$.obsoleteField+NULL:仅在lax模式下删除该 key;strict下因路径存在性检查失败而报错
数组和对象更新必须用 JSON_QUERY 包裹,否则全变成字符串
这是最常踩的坑:直接传字符串字面量,JSON_MODIFY 会把它当标量值自动加双引号转义。
- ❌ 错误:
JSON_MODIFY(@json, '$.skills', '["C#","T-SQL"]')→ 结果是"skills": "[\"C#\",\"T-SQL\"]"(一个字符串) - ✅ 正确:
JSON_MODIFY(@json, '$.skills', JSON_QUERY('["C#","T-SQL"]'))→ 得到真正的 JSON 数组 - ✅ 插入空数组:
JSON_MODIFY(@json, '$.tags', JSON_QUERY('[]')),不能用NULL(那会删掉整个tags键) - ✅ 插入对象:
JSON_MODIFY(@json, '$.profile', JSON_QUERY('{"age":30,"active":true}'))
类型安全要靠显式转换,别信隐式推导
JSON_MODIFY 不做类型推断,传什么类型就存什么——但 SQL Server 对 JSON 内部类型无强约束,所以你得自己兜底。
- 布尔值必须转
BIT:CONVERT(BIT, 1)或CONVERT(BIT, 'true'),否则会被当字符串 - 整数建议显式转
INT/BIGINT,避免小数点后零被当成decimal导致输出带.0 -
JSON_VALUE提取的是字符串,不能直接喂给JSON_MODIFY更新数值字段——先转类型再用 - 日期时间字段若需保持
ISO 8601格式,应确保输入是合法字符串(如'2026-09-29T00:29:00'),而非 SQL Server 的DATETIME值
性能与原子性边界要心里有数
JSON_MODIFY 是函数级操作,每次调用都返回新 nvarchar(max) 字符串,底层不复用原始内存。
- 大 JSON(>1 MB)高频更新时,CPU 和内存压力明显上升,不是“就地修改”的字面意思
- 无法只更新 JSON 中某个嵌套字段而不重写整个字段值——SQL Server 还是按完整列写入
- 如果业务要求强一致性(比如并发更新同一 JSON 字段),必须配合应用层锁或数据库行锁,
JSON_MODIFY本身不提供乐观/悲观并发控制 - 本机
json数据类型(SQL Server 2025+)虽提升解析效率,但JSON_MODIFY行为不变,仍生成新字符串


















