我在JSON和SQL Server上看过很多东西,但是找不到我想要的东西。
我想通过从另一个表中检索JSON值来更新一个表中的列。
让我们说一下下表:
表格:人
+-------+-----------+
| 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"}}] |
+-------+----------------------------------------------------------------+
现在的想法是将Johns的名字改成Jeff。
UPDATE people
SET name = JSON_QUERY(archive.json, '$values.old')
WHERE ID = 1
上面的SQL可能没有任何意义,但我只是想了解我目前正在尝试做的事情的逻辑。我希望这有道理。
如果需要更多信息,请询问。
答案 0 :(得分:1)
您可以使用openjson
和带有cross apply
的双with
来读取json。然后,您可以使用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
更新前:
更新后:
答案 1 :(得分:1)
我在上面的评论中问了你一些问题
两句话:我是对的,您混合了旧值和新值?我呢 正确,以上只是示例,您正在寻找 通用解决方案,其中更新可能会影响不同的列, 也许每行超过一个?至少JSON将允许更多 对象数组中的元素。
但是-首先-您可以尝试以下操作:
-模拟您的设置(感谢@Andrea,我用了您的)
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