JSON_MODIFY 没有循环的所有值
JSON_MODIFY all values without looping
参见下面的示例。我如何使用 JSON_MODIFY
或其他方式将所有“disc”值修改为“100”,而不必循环更新每个数组项?
create table #temp_data (json_text nvarchar(max))
insert into #temp_data select
'
"curr":"USD",
"items":[
{
"line":1,
"disc":10,
},
{
"line":2,
"disc":11
},
{
"line":3,
"disc":12,
}
]
}'
select * from #temp_data
一种方法是使用传统的 SQL DML UPDATE 将 json_text 替换为从现有的 JSON 派生的新片段。像这样
如果需要,可以添加 JSON_MODIFY。
drop table if exists #temp_data;
go
create table #temp_data (json_text nvarchar(max));
insert into #temp_data(json_text) values(
N'{
"curr":"USD",
"items":[
{
"line":1,
"disc":10
},
{
"line":2,
"disc":11
},
{
"line":3,
"disc":12
}
]
}');
update #temp_data
set json_text=( select json_value(d.json_text, N'strict $.curr') curr,
(select j2.line, j2.disc+100 as disc
from #temp_data td
cross apply openjson(td.json_text)
with(curr nvarchar(20),
items nvarchar(max) as json) j1
cross apply openjson(j1.items)
with(line int,
disc int) j2
for json path) items
from #temp_data d
for json path, without_array_wrapper);
select * from #temp_data;
{
"curr": "USD",
"items": [
{
"line": 1,
"disc": 210
},
{
"line": 2,
"disc": 211
},
{
"line": 3,
"disc": 212
}
]
}
无法在 JSON_MODIFY()
调用中使用通配符,因此一种可能的方法是执行以下步骤:
- 使用
OPENJSON()
和包含 line
键的显式模式从存储的 JSON 中解析 $.items
数组。
- 为此数组的每一项设置
disc
键的新值。
- 使用
FOR JSON PATH
再次生成 JSON。
- 将 table 更新为
JSON_MODIFY()
。
Table:
create table #temp_data (json_text nvarchar(max))
insert into #temp_data (json_text)
VALUES (N'
{
"curr":"USD",
"items":[
{"line":1, "disc":10},
{"line":2, "disc":11},
{"line":3, "disc":12}
]
}')
声明:
UPDATE #temp_data
SET json_text = JSON_MODIFY(
json_text,
'$.items',
(
SELECT line, 100 AS disc
FROM OPENJSON(json_text, '$.items') WITH (line int '$.line')
FOR JSON PATH
)
)
结果:
json_text
{
"curr":"USD",
"items":[{"line":1,"disc":100},{"line":2,"disc":100},{"line":3,"disc":100}]
}
我们实际上不需要解析 JSON 的其余部分,我们只需要 $.items
部分。所以我们可以 APPLY
属性 和 OPENJSON
,然后用 JSON_MODIFY
重新组合它:
UPDATE t
SET json_text = JSON_MODIFY(t.json_text, '$.items', v.items)
FROM temp_data t
CROSS APPLY (
SELECT line, disc = 100
FROM OPENJSON(t.json_text, '$.items') WITH (line int) AS items
FOR JSON PATH
) v(items);
在 WITH
块中,我们需要添加我们不修改的所有属性,然后在内部 SELECT
我们添加我们想要更改的任何列。
参见下面的示例。我如何使用 JSON_MODIFY
或其他方式将所有“disc”值修改为“100”,而不必循环更新每个数组项?
create table #temp_data (json_text nvarchar(max))
insert into #temp_data select
'
"curr":"USD",
"items":[
{
"line":1,
"disc":10,
},
{
"line":2,
"disc":11
},
{
"line":3,
"disc":12,
}
]
}'
select * from #temp_data
一种方法是使用传统的 SQL DML UPDATE 将 json_text 替换为从现有的 JSON 派生的新片段。像这样
如果需要,可以添加JSON_MODIFY。
drop table if exists #temp_data;
go
create table #temp_data (json_text nvarchar(max));
insert into #temp_data(json_text) values(
N'{
"curr":"USD",
"items":[
{
"line":1,
"disc":10
},
{
"line":2,
"disc":11
},
{
"line":3,
"disc":12
}
]
}');
update #temp_data
set json_text=( select json_value(d.json_text, N'strict $.curr') curr,
(select j2.line, j2.disc+100 as disc
from #temp_data td
cross apply openjson(td.json_text)
with(curr nvarchar(20),
items nvarchar(max) as json) j1
cross apply openjson(j1.items)
with(line int,
disc int) j2
for json path) items
from #temp_data d
for json path, without_array_wrapper);
select * from #temp_data;
{
"curr": "USD",
"items": [
{
"line": 1,
"disc": 210
},
{
"line": 2,
"disc": 211
},
{
"line": 3,
"disc": 212
}
]
}
无法在 JSON_MODIFY()
调用中使用通配符,因此一种可能的方法是执行以下步骤:
- 使用
OPENJSON()
和包含line
键的显式模式从存储的 JSON 中解析$.items
数组。 - 为此数组的每一项设置
disc
键的新值。 - 使用
FOR JSON PATH
再次生成 JSON。 - 将 table 更新为
JSON_MODIFY()
。
Table:
create table #temp_data (json_text nvarchar(max))
insert into #temp_data (json_text)
VALUES (N'
{
"curr":"USD",
"items":[
{"line":1, "disc":10},
{"line":2, "disc":11},
{"line":3, "disc":12}
]
}')
声明:
UPDATE #temp_data
SET json_text = JSON_MODIFY(
json_text,
'$.items',
(
SELECT line, 100 AS disc
FROM OPENJSON(json_text, '$.items') WITH (line int '$.line')
FOR JSON PATH
)
)
结果:
json_text
{
"curr":"USD",
"items":[{"line":1,"disc":100},{"line":2,"disc":100},{"line":3,"disc":100}]
}
我们实际上不需要解析 JSON 的其余部分,我们只需要 $.items
部分。所以我们可以 APPLY
属性 和 OPENJSON
,然后用 JSON_MODIFY
重新组合它:
UPDATE t
SET json_text = JSON_MODIFY(t.json_text, '$.items', v.items)
FROM temp_data t
CROSS APPLY (
SELECT line, disc = 100
FROM OPENJSON(t.json_text, '$.items') WITH (line int) AS items
FOR JSON PATH
) v(items);
在 WITH
块中,我们需要添加我们不修改的所有属性,然后在内部 SELECT
我们添加我们想要更改的任何列。