SQL Server 2016:不使用JSON_MODIFY为JSON字符串添加新值的方法
不用JSON_MODIFY和表存储,在SQL Server 2016中修改JSON字符串
嘿,这个需求有点意思——不用JSON_MODIFY也不碰表,纯靠字符串操作来修改JSON是吧?在SQL Server 2016里确实有可行的办法,不过得先提前说清楚:这种方法依赖JSON的格式规范(比如键值对的排版、空格情况),如果你的「随机JSON」格式波动很大,可能需要微调逻辑,但针对你给出的示例场景,完全能搞定。
针对你给出的示例的快速解法
先看你提供的例子:把{ "a": { "b": "val"} }修改为{ "a": { "b": "val", "c": "NEW"} }。我们可以通过字符串定位和替换来实现,核心用CHARINDEX找插入位置,STUFF函数插入新的键值对:
DECLARE @OriginalJSON NVARCHAR(MAX) = '{ "a": { "b": "val"} }'; DECLARE @NewKey NVARCHAR(50) = 'c'; DECLARE @NewValue NVARCHAR(50) = 'NEW'; -- 定位到内层对象的闭合大括号位置(在"b": "val"之后) DECLARE @InsertPos INT = CHARINDEX('}', @OriginalJSON, CHARINDEX('"b": "val"', @OriginalJSON)); -- 插入新的键值对 DECLARE @ModifiedJSON NVARCHAR(MAX) = STUFF( @OriginalJSON, @InsertPos, 0, ', "' + @NewKey + '": "' + @NewValue + '"' ); SELECT @ModifiedJSON AS Result;
执行这段代码后,就能得到你想要的结果:{ "a": { "b": "val", "c": "NEW"} }。
更通用的解法(适配内层对象有多个键的情况)
如果你的JSON内层对象有多个键(比如{ "a": { "b": "val", "d": "test"} }),上面的定位逻辑就不够用了。这时候可以通过括号计数来精准找到内层对象的闭合位置,避免依赖特定键的存在:
DECLARE @OriginalJSON NVARCHAR(MAX) = '{ "a": { "b": "val", "d": "test"} }'; DECLARE @NewKey NVARCHAR(50) = 'c'; DECLARE @NewValue NVARCHAR(50) = 'NEW'; -- 先找到内层对象的起始大括号位置(在"a":之后) DECLARE @InnerStart INT = CHARINDEX('{', @OriginalJSON, CHARINDEX('"a":', @OriginalJSON)) + 1; DECLARE @InnerEnd INT = @InnerStart; DECLARE @BracketCount INT = 1; -- 循环计数括号,找到内层对象的闭合大括号 WHILE @BracketCount > 0 AND @InnerEnd <= LEN(@OriginalJSON) BEGIN SET @InnerEnd = @InnerEnd + 1; IF SUBSTRING(@OriginalJSON, @InnerEnd, 1) = '{' SET @BracketCount += 1; IF SUBSTRING(@OriginalJSON, @InnerEnd, 1) = '}' SET @BracketCount -= 1; END -- 根据内层对象是否为空,决定插入时是否加逗号 DECLARE @InsertContent NVARCHAR(MAX) = CASE WHEN SUBSTRING(@OriginalJSON, @InnerEnd - 1, 1) = '{' THEN ' "' + @NewKey + '": "' + @NewValue + '"' ELSE ', "' + @NewKey + '": "' + @NewValue + '"' END; -- 插入新键值对 DECLARE @ModifiedJSON NVARCHAR(MAX) = STUFF(@OriginalJSON, @InnerEnd, 0, @InsertContent); SELECT @ModifiedJSON AS Result;
这个方法能处理内层对象为空(比如"a": {})、有多个键的情况,通用性更强。
注意事项
- 这种纯字符串处理的方法不适合有复杂转义字符、嵌套数组的JSON,比如如果值里包含双引号或者大括号,会破坏JSON结构。
- 如果你的JSON格式不固定(比如键值对之间有大量随机空格),可能需要先对JSON做格式化处理(比如用
JSON_QUERY配合FOR JSON PATH来标准化格式),再进行字符串操作。 - 说实话,
JSON_MODIFY是SQL Server官方提供的JSON操作函数,稳定性和通用性都比字符串处理强,如果没有特殊限制,还是优先考虑它。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

