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

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

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

我认为您不能对 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"}