JSON\按索引修改JSON数组中的插入值
按索引在json数组中是否有任何insert或update值。 我有一个列包含这样的值:JSON\按索引修改JSON数组中的插入值,json,sql-server,tsql,Json,Sql Server,Tsql,按索引在json数组中是否有任何insert或update值。 我有一个列包含这样的值: ["qwe","123"] 我想在中间插入新值: ["qwe","asd","123"] 或删除一个: ["123"] 如何使用JSON\u MODIFY 我只添加了最后一个值: select JSON_MODIFY([Column], 'append $', '') from MyTable 或更新将中间值更改为NUL: select JSON_MODIFY([Column], '$[1]',
["qwe","123"]
我想在中间插入新值:
["qwe","asd","123"]
或删除一个:
["123"]
如何使用JSON\u MODIFY
我只添加了最后一个值:
select JSON_MODIFY([Column], 'append $', '')
from MyTable
或更新将中间值更改为NUL:
select JSON_MODIFY([Column], '$[1]', NULL)
from MyTable
然后将其替换为零。我认为这不是一种正常的方法 我只找到了下面的方法
-- create and fill #TestData
SELECT '["qwe","asd","123"]' json_str
INTO #TestData
UNION ALL
SELECT '["zxc","asd","321"]'
UNION ALL
SELECT '[]'
UNION ALL
SELECT '["qwe","asd","12\"3"]' -- escaped quotes
UNION ALL
SELECT '["qwe","asd","<123>"]' -- special characters
-- delete demo
SELECT
json_str,
JSON_QUERY(CONCAT('[',STUFF((
SELECT CONCAT(',"',REPLACE([value],'"','\"'),'"')
FROM OPENJSON(json_str, '$')
WHERE [key]<>1 -- exclude element with index 1
ORDER BY [key]
FOR XML PATH('')),1,1,''),']')) new_json_str
FROM #TestData
-- insert demo
SELECT
json_str,
JSON_QUERY(CONCAT('[',STUFF((
SELECT CONCAT(',"',REPLACE([value],'"','\"'),'"')
FROM
(
SELECT 1 RowPriority,[key],[value]
FROM OPENJSON(json_str, '$')
UNION ALL
SELECT
2 RowPriority,
0, -- add after key with index 0
'new value' -- value
) q
ORDER BY [key],RowPriority -- sort values
FOR XML PATH('')),1,1,''),']')) new_json_str
FROM #TestData
DROP TABLE #TestData
最后一个变量可能会更好,因为XML路径(“”)的构造将替换一些特殊字符(例如:
如果要在最后一个值之前插入新值,可以将最后一个值再次附加为n+1
,然后替换n
值:
DECLARE @Data TABLE
(
[ID] INT
,[Column] NVARCHAR(MAX)
);
INSERT INTO @Data ([ID], [Column])
VALUES (1, '["qwe","123"]');
SELECT JSON_MODIFY(JSON_MODIFY([Column], 'append $', JSON_VALUE([Column], '$[1]')), '$[1]', 'asd')
FROM @Data
WHERE [ID] = 1;
现在,如果我们有很多元素,如果我们想在第二个或第三个索引中插入新元素,上面的方法将不起作用,因为我们需要交换新索引之后的所有值
为此,我们可以使用OPNEJSON
函数分割值,然后插入具有适当索引的新值,并使用FOR XML
或SRING AGGREGATE
函数连接值
DECLARE @Data TABLE
(
[ID] INT
,[Column] NVARCHAR(MAX)
);
INSERT INTO @Data ([ID], [Column])
VALUES (2, '["qwe","123", "125" ,"126"]');
SELECT
'[' +
STUFF
(
(
SELECT ',' + [value] AS [value]
FROM
(
SELECT JS.[value]
,JS.[key] * 1.0
FROM @Data DS
CROSS APPLY OPENJSON([Column]) JS
WHERE DS.[ID] = 2
UNION ALL
SELECT 'asd'
,0.1
) DS ([value], [key])
ORDER BY [key]
FOR XML PATH, TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
)
+']';
如果项包含转义引号,则删除失败:[“1”,“2\”]我已设法使用以下代码从中间删除项:REPLACE(REPLACE(REPLACE(JSON_MODIFY(JSON_str,$[1],“,”,“,”,“,”,“,”,“,”,“,”,“,”,“,”,“,”,“[”)我已将hackREPLACE([value],“,”,“,“,”)添加到所有查询中。)您可以再次检查。我已在旧查询中添加了orderby[key]
,并为XML路径(“”)
添加了另一个带有STRING\u AGG
的变量。
DECLARE @Data TABLE
(
[ID] INT
,[Column] NVARCHAR(MAX)
);
INSERT INTO @Data ([ID], [Column])
VALUES (1, '["qwe","123"]');
SELECT JSON_MODIFY(JSON_MODIFY([Column], 'append $', JSON_VALUE([Column], '$[1]')), '$[1]', 'asd')
FROM @Data
WHERE [ID] = 1;
DECLARE @Data TABLE
(
[ID] INT
,[Column] NVARCHAR(MAX)
);
INSERT INTO @Data ([ID], [Column])
VALUES (2, '["qwe","123", "125" ,"126"]');
SELECT
'[' +
STUFF
(
(
SELECT ',' + [value] AS [value]
FROM
(
SELECT JS.[value]
,JS.[key] * 1.0
FROM @Data DS
CROSS APPLY OPENJSON([Column]) JS
WHERE DS.[ID] = 2
UNION ALL
SELECT 'asd'
,0.1
) DS ([value], [key])
ORDER BY [key]
FOR XML PATH, TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
)
+']';