2009-12-11 72 views
6

我有兩個XML變量說@res,@student在SQL Server 2005中如何使用XQuery將xml插入另一個xml中的節點?

@res一個存儲過程包含

<Subject>English</Subject> 
<Marks>67</Marks> 
<Subject>Science</Subject> 
<Marks>75</Marks> 

@student包含:

<Student> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Result /> 
    <Attendance>50</Attendance> 
</Student> 

我需要將xml的@res插入節點結果使用XQuery在@student變量中。

如何實施?

請幫忙。

+0

增加了一個「hacky」字符串解析解決方案,該解決方案也適用於SQL Server 2005 - 並不漂亮,但它應該可以工作。 –

回答

31

在SQL Server 2008中,這是很容易:

DECLARE @res XML = '<Subject>English</Subject> 
<Marks>67</Marks> 
<Subject>Science</Subject> 
<Marks>75</Marks>' 


DECLARE @student XML = '<Student> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Result /> 
    <Attendance>50</Attendance> 
</Student>' 


SET @student.modify('insert sql:variable("@res") as first into (/Student/Result)[1]') 

SELECT @student 

這給了我輸出:

<Student> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Result> 
    <Subject>English</Subject> 
    <Marks>67</Marks> 
    <Subject>Science</Subject> 
    <Marks>75</Marks> 
    </Result> 
    <Attendance>50</Attendance> 
</Student> 

不幸的是,被引入到呼叫.modify()並使用INSERT語句可以在sql:variable的能力僅適用於SQL Server 2008 - 在SQL Server 2005中不起作用。

我看不出在SQL Server 2005中如何做到這一點o不是訴諸回醜字符串解析和替換療法:

SET @student = 
    CAST(REPLACE(CAST(@student AS VARCHAR(MAX)), 
       '<Result/>', 
       '<Result>' + CAST(@res AS VARCHAR(MAX)) + '</Result>') AS XML) 

馬克

0

你也可以嘗試回去關係數據和比回XML;是這樣的:

DECLARE @res xml = 
'<result> 
    <StudentID>1</StudentID> 
    <Subject>English</Subject> 
    <Marks>67</Marks> 
</result> 
<result> 
    <StudentID>1</StudentID> 
    <Subject>Science</Subject> 
    <Marks>75</Marks> 
</result>' 

DECLARE @student xml = 
'<Student> 
    <StudentID>1</StudentID> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Attendance>50</Attendance> 
</Student>' 

; 
WITH cte_1 
     AS (SELECT t.c.value('StudentID[1]', 'int') AS [StudentID] 
        ,t.c.value('Subject[1]', 'varchar(50)') AS [Subject] 
        ,t.c.value('Marks[1]', 'int') AS [Marks] 
      FROM @res.nodes('/result') AS t (c) 
      ), 
     cte_2 
     AS (SELECT t.c.value('StudentID[1]', 'int') AS [StudentID] 
        ,t.c.value('Name[1]', 'varchar(50)') AS [Name] 
        ,t.c.value('Roll[1]', 'int') AS [Roll] 
        ,t.c.value('Attendance[1]', 'int') AS [Attendance] 
      FROM @student.nodes('/Student') AS t (c) 
      ) 
    SELECT student.StudentID 
     ,student.[Name] 
     ,student.Roll 
     ,student.Attendance 
     ,(SELECT result.[Subject] 
        ,result.Marks 
      FROM cte_1 AS result 
      WHERE student.StudentID = result.StudentID 
      FOR 
      XML AUTO 
       ,TYPE 
       ,ELEMENTS 
     ) 
    FROM cte_2 AS student 
FOR  XML AUTO 
      ,ELEMENTS 

返回:

<student> 
    <StudentID>1</StudentID> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Attendance>50</Attendance> 
    <result> 
    <Subject>English</Subject> 
    <Marks>67</Marks> 
    </result> 
    <result> 
    <Subject>Science</Subject> 
    <Marks>75</Marks> 
    </result> 
</student> 

不完全是你的榜樣,但接近。

7

這將在2005年SQL工作,主要是一個XQuery解決方案:

DECLARE @res xml 

SET @res = 
'<Subject>English</Subject> 
<Marks>67</Marks> 
<Subject>Science</Subject> 
<Marks>75</Marks>' 

DECLARE @student xml 
SET @student = 
'<Student> 
    <Name>XYZ</Name> 
    <Roll>15</Roll> 
    <Result /> 
    <Attendance>50</Attendance> 
</Student>' 

DECLARE @final XML 

SET @final = CAST(CAST(@student AS VARCHAR(MAX)) + '<test>' + CAST(@res AS VARCHAR(MAX)) + '</test>' AS XML) 

SET @final.modify('insert /test/* into (/Student/Result)[1]') 
SET @final.modify('delete /test') 

SELECT @final 

您可以設置@student變量在這一點上@final,如果你需要做的。節點的「測試」名稱正是我選擇使用的名稱。只要它不會出現在您的XML中,您可以使用任何名稱

您基本上只是將兩個XML字符串放在一起,以便它們都可以同時用於xquery。

相關問題