Обновление столбца с данными JSON в другой таблице - PullRequest
0 голосов
/ 04 декабря 2018

Я много видел в JSON и SQL Server, но не смог найти то, что искал.

Я хочу обновить столбцы в одной таблице, извлекая значения JSON из другой таблицы.

Допустим, у меня есть таблица ниже:

таблица: people

+-------+-----------+
|   id  |   name    |  
+-------+-----------+
|   1   |   John    |      
|   2   |   Mary    |     
|   3   |   Jeff    |       
|   4   |   Bill    |       
|   5   |   Bob     |   
+-------+-----------+

И давайте представим, что у меня есть еще одна таблица, заполненная строками в формате JSON, напримерследующее:

таблица: архив

+-------+----------------------------------------------------------------+
|   id  |   json                                                         |  
+-------+----------------------------------------------------------------+
|   1   |[{ "Column":"name","values": { "old": "Jeff", "new": "John"}}]  |      
|   2   |[{ "Column":"name","values": { "old": "Rose", "new": "Mary"}}]  |     
+-------+----------------------------------------------------------------+

Теперь идея состоит в том, чтобы изменить имя Джона на Джефф.

UPDATE people
SET name = JSON_QUERY(archive.json, '$values.old')
WHERE ID = 1

Приведенный выше SQLможет не иметь смысла, но я просто пытаюсь понять мою нынешнюю логику того, что я пытаюсь сделать.Надеюсь, в этом есть какой-то смысл.

Если вам нужна дополнительная информация, пожалуйста, спросите.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Я задал вам несколько вопросов в комментарии выше

Два замечания: Я прав, что вы смешали старые и новые значения?И я прав, что вышеприведенный пример - всего лишь пример, и вы ищете универсальное решение, в котором обновления могут влиять на разные столбцы, возможно, даже больше, чем по одному на строку?По крайней мере, JSON допускает больше элементов в массиве объектов.

Но - в качестве начала - вы можете попробовать это:

- макет вашей установки (спасибо @Андреа, я использовал твой)

declare @people table (id int, [name] varchar(50))

insert into @people values
 (1, 'John')    
,(2, 'Mary')   
,(3, 'Jeff')     
,(4, 'Bill')     
,(5, 'Bob' )

declare @json table  (id int, [json] nvarchar(max))
insert into @json values
 (1,'[{ "Column":"name","values": { "old": "Jeff", "new": "John"}}]')     
,(2,'[{ "Column":"name","values": { "old": "Rose", "new": "Mary"}}]')

- Это - по крайней мере - вернет все, что тебе нужно.Остальное - предположительно - динамическое построение операторов и EXEC():

SELECT p.*
      ,A.[Column]
      ,JSON_VALUE(A.[values],'$.old') AS OldValue
      ,JSON_VALUE(A.[values],'$.new') As NewValue
FROM @people p
INNER JOIN @json j ON p.id=j.id
CROSS APPLY OPENJSON(j.[json]) 
WITH([Column] VARCHAR(100), [values] NVARCHAR(MAX) AS JSON) A;

Результат (кажется, что старое и новое ошибочно):

id  name    Column  OldValue    NewValue
1   John    name    Jeff        John
2   Mary    name    Rose        Mary
0 голосов
/ 04 декабря 2018

Вы можете прочитать свой JSON, используя openjson и двойное cross apply с предложением with.Затем вы можете использовать update from для изменения значений в @people:

declare @people table (id int, [name] varchar(50))

insert into @people values
 (1, 'John')    
,(2, 'Mary')   
,(3, 'Jeff')     
,(4, 'Bill')     
,(5, 'Bob' )

declare @json table  (id int, [json] nvarchar(max))
insert into @json values
 (1,'[{ "Column":"name","values": { "old": "Jeff", "new": "John"}}]')     
,(2,'[{ "Column":"name","values": { "old": "Rose", "new": "Mary"}}]')    

update @people
set [name] = d.old
from @people p
inner join 
(
     select id
          , c.old
          , c.new
     from @json a
     cross apply openjson(json) with 
     (
         [Column] nvarchar(50)
       , [values] nvarchar(MAX) as JSON
     ) b
     cross apply openjson(b.[values]) with 
     (
         old nvarchar(50)
       , new nvarchar(50)
     ) c
) d 
on p.id = d.id

Перед обновлением:

enter image description here

После обновления:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...