2009-02-11 46 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