2009-02-11 49 views
2

我有一个从单个select语句创建的@XML文档。在SQL 2005中使用XML.modify()在多个XML节点中插入属性

<root> 
<node> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
</node> 
<node> 
    ...... 
</node> 
</root> 

我想为此文档插入xsi:nil作为'targetNode'的属性。

@XML.modify('insert attribute xsi:nil {"true"} into (root/node/node1/targetNode) [1]') 

以上将在@XML文档中将属性插入targetNode的第一次出现。然而,insert语句只能在单个节点上运行。有什么方法可以将此属性插入到@XML文档中的targetNode的所有实例中。

回答

1

您可以在选择这样做,您正在使用,以创建XML,使用XSINILL参数。

http://msdn.microsoft.com/en-us/library/ms178079.aspx

(这里是一个非常粗略的例子)

--create 2 tables and put some data in them 
create table node 
(
    id int identity(1,1) primary key, 
    node int 
) 
GO 
create table node1 
(
    id int identity(1,1) primary key, 
    nodeid int foreign key references node(id), 
    targetnode int 
) 
GO 

insert into node 
select 1 
GO 5 

insert into node1 
select 1,2 
union 
select 2,null 
union 
select 3,2 
union 
select 4,null 
-- 

--select statement to generate the xml 
SELECT TOP(1) 
    (SELECT 
     ( SELECT targetnode 
     FROM node1 
     WHERE nodeid = node.id 
     FOR XML AUTO, 
     ELEMENTS XSINIL, 
     TYPE 
    ) 
    FROM node FOR XML AUTO, 
    ELEMENTS, 
    TYPE 
    ) 
FROM node FOR XML RAW('root'), 
     ELEMENTS 
2

这是修改功能无法实现的。它只适用于单个节点。

您可以将其作为字符串进行操作,但在某些情况下,这绝对是丑陋的,可能是错误的,具体取决于XML的实际结构。

像这样:

declare @xml as xml 
set @xml = '<root> 
<node> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
    <node1> 
    <targetNode> 
    </targetNode> 
    </node1> 
</node> 
</root> 
' 

set @xml = replace(cast(@xml as nvarchar(max)), '<targetNode/>', '<targetNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />') 
select @xml 
2

我发现DML操作在多个节点 http://blogs.msdn.com/b/denisruc/archive/2005/09/19/471562.aspx

一个简单而优雅的解决方案的想法是算多少个节点并逐个修改:

DECLARE @iCount int 
SET @iCount = @var.value('count(root/node/node1/targetNode)','int') 

DECLARE @i int 
SET @i = 1 

WHILE (@i <= @iCount) 
BEGIN 
    @xml.modify('insert attribute xsi:nil {"true"} into (root/node/node1/targetNode)[sql:variable("@i")][1]') 
    SET @i = @i + 1 
END