在单个XQuery中为SQL Server删除多个节点

Ant*_*ton 5 xml sql-server xpath xquery sql-server-2005

我有:

  1. 带有xml类型列的表(ID列表)
  2. 一个XML类型参数(也ID列表)

从列中删除与参数中的节点匹配的节点的最佳方法是什么,同时保持任何不匹配的节点不变?

例如

declare @table table (
    [column] xml
)

insert @table ([column]) values ('<r><i>1</i><i>2</i><i>3</i></r>')

declare @parameter xml
set @parameter = '<r><i>1</i><i>2</i></r>'

-- this is the problem
update @table set [column].modify('delete (//i *where text() matches @parameter*)')
Run Code Online (Sandbox Code Playgroud)

MSDN文档表明它应该是可能的(在SQL Server 2005中的XQuery简介中):

可以容易地修改该存储过程以接受包含一个或多个技能元素的XML片段,从而允许用户通过单个存储过程的调用来删除多个技能节点.

jve*_*ema 3

虽然以这种方式删除有点尴尬,但您可以进行更新来更改数据,前提是您的数据很简单(例如您给出的示例)。以下查询基本上将两个 XML 字符串拆分为表,连接它们,排除非空(匹配)值,然后将其转换回 XML:

UPDATE @table 
SET [column] = (
    SELECT p.i.value('.','int') AS c
    FROM [column].nodes('//i') AS p(i)
    OUTER APPLY (
        SELECT x.i.value('.','bigint') AS i
        FROM @parameter.nodes('//i') AS x(i)
        WHERE p.i.value('.','bigint') = x.i.value('.','int')
    ) a
    WHERE a.i IS NULL
    FOR XML PATH(''), TYPE
)
Run Code Online (Sandbox Code Playgroud)