Обновить массив JSON, используя SQL Server - PullRequest
1 голос
/ 04 августа 2020

У меня есть JSON, как показано ниже:

{
 "property": {
  "commonProperty": "abc",
  "Items": [
   {
    "ID": 1,
    "Name": "a"
   },
   {
    "ID": 2,
    "Name": "a"
   },
   {
    "ID": 3,
    "Name": "b"
   }
  ]
 }
}

И я хочу обновить имена до «c», где сейчас «a», используя SQL Server (так что я хотите получить результат, как показано ниже).

{
 "property": {
  "commonProperty": "abc",
  "Items": [
   {
    "ID": 1,
    "Name": "c"
   },
   {
    "ID": 2,
    "Name": "c"
   },
   {
    "ID": 3,
    "Name": "b"
   }
  ]
 }
}

Насколько я знаю, я не могу использовать JSON_MODIFY, потому что он не обрабатывает запросы внутри своих аргументов и OPENJSON не может быть обновлен. Есть ли какой-нибудь метод, который я могу использовать?

EDIT note: добавлено общее свойство над элементами.

1 Ответ

2 голосов
/ 04 августа 2020

Вы можете попробовать один из следующих вариантов:

  • Разобрать массив '$.property.Items' JSON как таблицу, используя OPENJSON(), выполнить обновление, вывести содержимое таблицы как JSON, используя FOR JSON и измените исходный JSON с помощью JSON_MODIFY():
  • Создайте динамический c оператор. Вы можете изменить ввод JSON, используя JSON_MODIFY() и соответствующий path. path должен быть определен как литерал или из SQL Server 2017 как переменная, но использование подстановочного знака невозможно (например, оператор SELECT @json = JSON_MODIFY(@json, '$.property.Items[0].Name', N'c') изменяет первый элемент в массиве Items JSON) .

JSON:

DECLARE @json nvarchar(max) = N'{
   "property":{
      "commonProperty":"abc",
      "Items":[
         {
            "ID":1,
            "Name":"a"
         },
         {
            "ID":2,
            "Name":"a"
         },
         {
            "ID":3,
            "Name":"b"
         }
      ]
   }
}'

Оператор (который анализирует JSON как таблицу, изменяет таблицу и выводит содержимое таблицы как JSON):

SELECT @json = JSON_MODIFY(
   @json,
   '$.property.Items',
   (
   SELECT 
      ID AS 'ID', 
      CASE WHEN Name = N'a' THEN N'c' ELSE Name END AS 'Name'
   FROM OPENJSON(@json, '$.property.Items') WITH (ID int, Name nvarchar(50))
   FOR JSON PATH
   )
)

Dynami c инструкция:

DECLARE @stm nvarchar(max)
SET @stm = (
   SELECT N'SET @json = JSON_MODIFY(@json, ''$.property.Items[' + [key] + N'].Name'', N''c''); '
   FROM OPENJSON(@json, '$.property.Items')
   WHERE JSON_VALUE([value], '$.Name') = N'a'
   FOR XML PATH('')
)

PRINT @stm
EXEC sp_executesql @stm, N'@json nvarchar(max) OUTPUT', @json OUTPUT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...