SQL-SERVER:JSON_MODIFY 在 json 列与 "contains" 字段匹配
SQL-SERVER: JSON_MODIFY on json column with "contains" field match
我正在尝试弄清楚如何修改存储在我的 table(SQL 服务器)的列中的 json。
我想删除 JSON 的 属性,只有当它与特定字符串匹配时。
假设我们在 table 中有一条记录,这个 JSON 在名为 "profile" (nvarchar(max)) 的列中:
{
name: "goofy",
class_cod_x: "1345",
}
然后另一条记录显示这个JSON:
{
name: "donald",
class_cod_y: "1457",
}
现在我们要搜索并更新我们记录中的所有 JSON,其中包含 属性,startsWith "class_cod"。
我想从该列中删除所有 "class_cod.." 属性。
我可以想象这样的查询:
UPDATE myTable SET profile = JSON_MODIFY( profile , "startsWith(class_cod)" , null)
这可能吗?在那种情况下,哪个是正确的语法?
提前致谢!
更新
预期输出:
{
name: "goofy",
}
和
{
name: "donald",
}
"class_cod" 字段已完全删除。
更新 2
SQL 服务器版本:Microsoft SQL Server 2016 (RTM) - 13.0.1601.5 (X64)
"name" 和 "class_cod.." 不是 json 列中唯一可能的字段。
JSON 基于可能配置的枚举。
是否有可能一个JSON包含多个"class_cod.."字段。 (极其罕见但有可能)
{
name: mario,
class_cod_10: 22,
class_cod_20: 31,
}
一种方法是创建动态更新语句并手动 运行 生成更新查询。像这样。
SELECT 'UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,''$.' +x.[key]+ ''', null)'
FROM MYTABLE T
CROSS APPLY OPENJSON (profile, '$') x
WHERE x.[key] LIKE '%class_cod%'
此查询将创建如下更新语句列表。
UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,'$.class_cod_x', null)
UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,'$.class_cod_y', null)
假设:每个 JSON 记录仅包含一次键 class_cod_*
。希望只有有限的行可以手动 运行 更新语句
我认为您不能对 JSON_MODIFY()
中的 path
参数使用通配符,并且如果 profile
列中的 JSON 有多个 class_cod_*
键,您可以尝试生成并执行动态语句。最后的语句包括一个 UPDATE
语句,用于 table 中所有行的所有 JSON 对象中的每个不同的 class_cod_*
键。请注意,您需要使用 lax
模式(默认)来指定路径引用的 属性 不必存在:
Table:
CREATE TABLE Data (profile nvarchar(max));
-- Rows with one `class_cod_*` key
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345"}')
INSERT INTO Data (profile) VALUES (N'{"name":"donald","class_cod_y":"1457"}')
-- Row without `class_cod_*` key
INSERT INTO Data (profile) VALUES (N'{"name":"tom"}')
-- Row with one `class_cod_*` key and other keys
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345","age":10}')
-- Row with two `class_cod_*` keys
INSERT INTO Data (profile) VALUES (N'{"name":"jerry", "class_cod_x":"1345", "class_cod_y":"1345"}')
声明:
DECLARE @stm nvarchar(max)
SELECT @stm = (
SELECT CONCAT(
CONCAT('UPDATE Data SET profile = JSON_MODIFY(profile, ''lax $."', t.[key], '"'', null)'),
'; '
)
FROM (
SELECT DISTINCT j.[key]
FROM Data d
CROSS APPLY OPENJSON(d.profile) j
WHERE j.[key] LIKE N'class_cod_%'
) t
FOR XML PATH('')
)
PRINT @stm
EXEC sp_executesql @stm
结果:
profile
{"name":"goofy"}
{"name":"donald"}
{"name":"tom"}
{"name":"goofy","age":10}
{"name":"jerry"}
我正在尝试弄清楚如何修改存储在我的 table(SQL 服务器)的列中的 json。
我想删除 JSON 的 属性,只有当它与特定字符串匹配时。
假设我们在 table 中有一条记录,这个 JSON 在名为 "profile" (nvarchar(max)) 的列中:
{
name: "goofy",
class_cod_x: "1345",
}
然后另一条记录显示这个JSON:
{
name: "donald",
class_cod_y: "1457",
}
现在我们要搜索并更新我们记录中的所有 JSON,其中包含 属性,startsWith "class_cod"。
我想从该列中删除所有 "class_cod.." 属性。
我可以想象这样的查询:
UPDATE myTable SET profile = JSON_MODIFY( profile , "startsWith(class_cod)" , null)
这可能吗?在那种情况下,哪个是正确的语法? 提前致谢!
更新 预期输出:
{
name: "goofy",
}
和
{
name: "donald",
}
"class_cod" 字段已完全删除。
更新 2
SQL 服务器版本:Microsoft SQL Server 2016 (RTM) - 13.0.1601.5 (X64)
"name" 和 "class_cod.." 不是 json 列中唯一可能的字段。 JSON 基于可能配置的枚举。
是否有可能一个JSON包含多个"class_cod.."字段。 (极其罕见但有可能)
{ name: mario, class_cod_10: 22, class_cod_20: 31, }
一种方法是创建动态更新语句并手动 运行 生成更新查询。像这样。
SELECT 'UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,''$.' +x.[key]+ ''', null)'
FROM MYTABLE T
CROSS APPLY OPENJSON (profile, '$') x
WHERE x.[key] LIKE '%class_cod%'
此查询将创建如下更新语句列表。
UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,'$.class_cod_x', null)
UPDATE MYTABLE SET PROFILE=JSON_MODIFY(profile ,'$.class_cod_y', null)
假设:每个 JSON 记录仅包含一次键 class_cod_*
。希望只有有限的行可以手动 运行 更新语句
我认为您不能对 JSON_MODIFY()
中的 path
参数使用通配符,并且如果 profile
列中的 JSON 有多个 class_cod_*
键,您可以尝试生成并执行动态语句。最后的语句包括一个 UPDATE
语句,用于 table 中所有行的所有 JSON 对象中的每个不同的 class_cod_*
键。请注意,您需要使用 lax
模式(默认)来指定路径引用的 属性 不必存在:
Table:
CREATE TABLE Data (profile nvarchar(max));
-- Rows with one `class_cod_*` key
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345"}')
INSERT INTO Data (profile) VALUES (N'{"name":"donald","class_cod_y":"1457"}')
-- Row without `class_cod_*` key
INSERT INTO Data (profile) VALUES (N'{"name":"tom"}')
-- Row with one `class_cod_*` key and other keys
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345","age":10}')
-- Row with two `class_cod_*` keys
INSERT INTO Data (profile) VALUES (N'{"name":"jerry", "class_cod_x":"1345", "class_cod_y":"1345"}')
声明:
DECLARE @stm nvarchar(max)
SELECT @stm = (
SELECT CONCAT(
CONCAT('UPDATE Data SET profile = JSON_MODIFY(profile, ''lax $."', t.[key], '"'', null)'),
'; '
)
FROM (
SELECT DISTINCT j.[key]
FROM Data d
CROSS APPLY OPENJSON(d.profile) j
WHERE j.[key] LIKE N'class_cod_%'
) t
FOR XML PATH('')
)
PRINT @stm
EXEC sp_executesql @stm
结果:
profile
{"name":"goofy"}
{"name":"donald"}
{"name":"tom"}
{"name":"goofy","age":10}
{"name":"jerry"}