JSON\按索引修改JSON数组中的插入值

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]',

按索引在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]', 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],“,”,“,”,“,”,“,”,“,”,“,”,“,”,“,”,“,”,“[”)我已将hack
REPLACE([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
    ,''
)
+']';