SQL-SERVER:具有“包含”字段匹配项的json列上的JSON_MODIFY

问题描述 投票:0回答:2

我试图弄清楚如何修改存储在表(SQL SERVER)列中的json。

仅在与特定字符串匹配时,我才希望删除JSON的属性。

想象一下,我们在表中有一条记录,其中的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)

这可能吗?在那种情况下,哪种是正确的语法?预先感谢!

UPDATE预期输出:

{ 
  name: "goofy",
}

{ 
  name: "donald",
}

“ class_cod”字段已完全删除。

sql json sql-server nvarchar
2个回答
0
投票

一种方法是创建动态更新语句并手动运行生成的更新查询。像这样的东西。

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_*一次。希望只有有限的行可以在其中手动运行更新语句

Check Demo Here


0
投票

解决方案:

我认为您不能对path中的JSON_MODIFY()参数使用通配符。但是,如果您使用SQL Server 2017+,并且profile列中的JSON对象只有一个class_cod_*键,则可以将JSON_MODIFY()与变量一起用作path的值和以下语句:

表格:

CREATE TABLE Data (profile nvarchar(max));
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345"}')
INSERT INTO Data (profile) VALUES (N'{"name":"donald","class_cod_y":"1457"}')
INSERT INTO Data (profile) VALUES (N'{"name":"tom"}')
INSERT INTO Data (profile) VALUES (N'{"name":"goofy","class_cod_x":"1345","age":10}')

声明:

UPDATE Data
SET profile = JSON_MODIFY(profile, CONCAT('$."', j.[key], '"'), NULL)
FROM Data d
CROSS APPLY OPENJSON(d.profile) j
WHERE j.[key] LIKE N'class_cod%'   

结果:

profile
{"name":"goofy"}
{"name":"donald"}
{"name":"tom"}
{"name":"goofy","age":10}

附加选项:

如果profile列中的JSON具有多个class_cod_*密钥,作为一个附加选项,您可以尝试生成和执行动态语句(SQL Server 2017+需要使用STRING_AGG进行聚合,用于SQL Server 2016,您应该使用FOR XML PATH(''))。请注意,您需要使用lax模式(默认设置)来指定path引用的属性不必存在:

DECLARE @stm nvarchar(max)
SELECT @stm = STRING_AGG(
   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

PRINT @stm
EXEC sp_executesql @stm
© www.soinside.com 2019 - 2024. All rights reserved.