如何在 SQL 中替换 json 字符串中的数字数组?

Posted

技术标签:

【中文标题】如何在 SQL 中替换 json 字符串中的数字数组?【英文标题】:How can I go about replacing a number array inside a json string in SQL? 【发布时间】:2019-12-28 03:07:13 【问题描述】:

SQL 中的数据在一个类似这样的单元格中包含一个很长的 JSON 字符串:


  "Name": "Example",
  "Results": [
    
      "ResultId": 0,
      "AnswerIds": "[1,2,33,4,5]"
    ,
    
      "ResultId": 1,
      "AnswerIds": "[2,3,4,55,6]"
    
  ]

我有一个替换 AnswerId 列表:将所有 2 替换为 7,将所有 3 替换为 8

我该如何为此编写脚本?

我可以使用 crossapply 和 JSON_Query 隔离 AnswerId,但不确定如何替换一个数组中的多个更改。

【问题讨论】:

对于基于 T-SQL 的解决方案,您可以从 Remove element from JSON array for whole table 获得想法。虽然该问题是关于删除数组成员的,但可以调整答案代码以更新数组成员。您可以使用 Json_modify 一次更新整个数组 - 因此,要将所有 2 替换为 7,您必须编写类似 se @json = JSON_MODIFY(@json,'$.Results[0].AnswerIds',JSON_QUERY('[1,7,33,4,5]')) 的内容 虽然这可能可以使用 T-SQL 解决,但 Sylens 在他的回答中显示的 javascript 解决方案要简单得多,并且可能比您在 T-SQL 中开箱即用的任何东西都具有更好的性能.如果您不介意往返,我会双手采用 JavaScript 解决方案。 【参考方案1】:

const json = 
  "Name": "Example",
  "Results": [
    
      "ResultId": 0,
      "AnswerIds": "[1,2,33,4,5]"
    ,
    
      "ResultId": 1,
      "AnswerIds": "[2,3,4,55,6]"
    
  ]


json.Results.forEach((itm, index)=> 
   const arr = JSON.parse(itm.AnswerIds);
   const replacedArray = arr.map(num=>
      if(num === 2) return 7;
      if(num === 3) return 8;
      return num;
   );
   json.Results[index].AnswerIds = JSON.stringify(replacedArray);
)

console.log(json);

这就是我所做的,获取 json.Results 数组并使用 forEach 循环对其进行迭代。

然后您可以访问每个结果的 AnswerIds 对象。

由于AnswerIds值是一个字符串,我们先将其转换为一个数组。

然后我们使用映射循环遍历该数组,并进行替换。

您可能想阅读 JS mapsJS foreachJSON.parseJSON.stringify强>

【讨论】:

【参考方案2】:

SQL Server 2016 支持 JSON,但您没有指定 SQL 版本。 使用DelimitedSplit8k 你可以这样做:

-- SAMPLE STRING
DECLARE @string VARCHAR(1000) = 
'
  "Name": "Example",
  "Results": [
    
      "ResultId": 0,
      "AnswerIds": "[1,2,33,4,5]"
    ,
    
      "ResultId": 1,
      "AnswerIds": "[2,3,4,55,6]"
    
  ]
';

-- SOLUTION
SELECT NewJSON = 
(
  SELECT
    IIF(i.pos = 0,IIF(i.pos>0 AND sub.string IN(2,3), x.x, sub.string),
      IIF(s2.ItemNumber=1,'"[','')+IIF(i.pos>0 AND sub.string IN(2,3),x.x,sub.string)) +
    IIF(s2.ItemNumber>LEAD(s2.ItemNumber,1) OVER (ORDER BY s.ItemNumber,s2.ItemNumber),']"',
      IIF(i.pos = 0,'',','))
  FROM        dbo.delimitedsplit8k(REPLACE(@string,CHAR(13),''),CHAR(10)) AS s
  CROSS APPLY (VALUES(CHARINDEX('"AnswerIds": "',s.item)))                AS i(pos)
  CROSS APPLY (VALUES(SUBSTRING(s.item, i.pos+14, 8000)))                 AS ss(item)
  CROSS APPLY dbo.delimitedsplit8k(ss.item,IIF(i.pos=0,CHAR(0),','))      AS s2
  CROSS APPLY (VALUES(IIF(i.pos=0,s.item,
                 REPLACE(REPLACE(s2.item,']"',''),'[',''))))              AS sub(string)
  CROSS APPLY (VALUES(REPLACE(REPLACE(sub.string,'2',7),'3',8)))          AS x(x)
  ORDER BY    s.ItemNumber, s2.ItemNumber
  FOR XML PATH('')
);

返回:


  "Name": "Example",
  "Results": [
    
      "ResultId": 0,
      "AnswerIds": "[1,7,33,4,5]"
    ,
    
      "ResultId": 1,
      "AnswerIds": "[7,8,4,55,6]"
    
  ]

【讨论】:

以上是关于如何在 SQL 中替换 json 字符串中的数字数组?的主要内容,如果未能解决你的问题,请参考以下文章

java中将map转成json时,如何将map中的整型数字在转成json后,变成字符串,而不是整型。

求sql部分字符替换语句

mybatis中的字符串替换

sql中如何批量替换字段里的字符串?

sqlserver中如何把字符串转换成数字

sql 替换指定字符串