Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert xml into a node in another xml using XQuery?

I have two xml variable say @res, @student in a stored proc in SQL server 2005.

@res contains

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

@student contains:

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

I need to insert the xml of @res into the node Result in @student variable using XQuery.

How to implement that?

Please help.

like image 553
Himadri Avatar asked Dec 11 '09 08:12

Himadri


People also ask

How do I query XML data in XQuery?

Querying in an XQuery contextIf your query invokes an XQuery expression directly, you must prefix it with the case-insensitive keyword XQUERY. To retrieve all of the XML documents previously inserted into the INFO column, you can use XQuery with either db2-fn:xmlcolumn or db2-fn:sqlquery.

How do I select a specific XML node in SQL Server?

You should use the query() Method if you want to get a part of your XML. If you want the value from a specific node you should use value() Method. Update: If you want to shred your XML to multiple rows you use nodes() Method.

What is used for replaceable content within an XML document?

The replaceData() method is used to replace data in a text node.


2 Answers

In SQL Server 2008, it's pretty easy:

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

That gives me the output:

<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>

Unfortunately, the ability to call .modify() and use a sql:variable in the insert statement was introduced with SQL Server 2008 only - doesn't work in SQL Server 2005.

I don't see how you could do this in SQL Server 2005, other than resorting back to ugly string parsing and replacement:

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

Marc

like image 101
marc_s Avatar answered Nov 15 '22 10:11

marc_s


This will work in SQL 2005 and is mostly an xquery solution:

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

You can set your @student variable to @final at that point if you need to do that. The name of "test" for the node was just what I chose to use. You can use any name as long as it will not already appear in your XML.

You basically just throw the two XML strings together so that they are both available to xquery at once.

like image 44
Tom H Avatar answered Nov 15 '22 10:11

Tom H