Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return XML from a Stored Procedure?

I created a Stored Procedure that returns XML and I would like to also return that XML in a method I created.

I'm having two issues. First, after doing some searching, it is not advised to use .ExecuteScalar(); because it truncates strings over 2033 characters.

So, I found a function called ExecuteXMlReader(), but in Visual Web Developer 2010 Express that runs on .NET 4.0 (C#) it is throwing the error "System.Data.SqlClient.SqlCommand' does not contain a definition for 'ExecuteXMlReader' and no extension method 'ExecuteXMlReader' accepting a first argument of type 'System.Data.SqlClient.SqlCommand' could be found"

Here is my stored procedure:

CREATE PROCEDURE dbo.GETReport
    (@ReportDate date)
AS
SELECT * FROM ReportTbl
WHERE ReportDate = @ReportDate
for xml auto, elements

set nocount on;

RETURN

Here is my method:

using System.Data;
using System.Data.SqlClient;

...

        //connect        
        SqlConnection conn = new SqlConnection("Data Source=localhost; User Id=foo; Password=foo; Initial Catalog=Database1");
        conn.Open();

        //create command
        SqlCommand cmd = new SqlCommand("dbo.GETReport", conn);
        cmd.Parameters.AddWithValue("@ReportDate", "3/24/2011"); 
        cmd.CommandType = CommandType.StoredProcedure;

        DataReader rd = cmd.ExecuteXMlReader(); //this is where error is occuring
        //also, it is throwing an error for DataReader as well saying there is no
        //type of namespace with that name
        rd.Read();

        string s = rd.ReadOuterXml(); //also dont know if this is how i should return the XML

Second, in addition to the ExecuteXMLReader() issue, I don't know if returning a string is the proper way of returning XML in the first place... Is there another object type I should convert it to?? Or another function I should use??

Thank you in advance!!

like image 496
AngeloS Avatar asked Mar 24 '11 18:03

AngeloS


People also ask

How can we return XML data from stored procedure in SQL Server?

1) Duplicate the stored procedure and add the FOR XML to the return statement(not pretty but works). 2) Have a second stored procedure call the non-XML version and just return the results using FOR XML . 3) Build the XML in the SELECT statement of the stored procedure.

Can we return from stored procedure?

You can use one or more RETURN statements in a stored procedure. The RETURN statement can be used anywhere after the declaration blocks within the SQL-procedure-body. To return multiple output values, parameters can be used instead. Parameter values must be set before the RETURN statement runs.


2 Answers

First, SqlCommand has a ExecuteXmlReader method, not ExecuteXMlReader as you wrote (this is misspelling). Second, SqlCommand.ExecuteXmlReader method returns a value of type XmlReader, not a DataReader as is in your example. So changing your code to:

using (XmlReader reader = cmd.ExecuteXmlReader()) {     while(reader.Read())     {         string s = reader.ReadOuterXml();         // do something with s     } } 

should solve the issue.

like image 161
Oleks Avatar answered Oct 14 '22 15:10

Oleks


I had trouble with the simple approach from @Alex and better luck with this approach:

// Execute a SqlCommand that you've created earlier. // (Don't forget your 'using' statements around SqlConnection, SqlCommand and XmlReader!) // This is where our XML will end up  var xmlDocument = new XmlDocument();  using (XmlReader xmlReader = cmd.ExecuteXmlReader()) {     // Now xmlReader has the XML but no root element so we can't     // load it straight into XmlDocument :( But we can use XPathDocument     // to add a node for us first.     var xp = new XPathDocument(xmlReader);     var xn = xp.CreateNavigator();     XmlNode root = xmlDocument.CreateElement("YourFavouriteRootElementName");     root.InnerXml = xn.OuterXml;     xmlDocument.AppendChild(root); }  // Now xmlDocument has all the XML you have dreamed of 

Using the reader.Read() ... var s = reader.ReadOuterXml() somehow missed some of the elements in my longer more complex XML. I didn't bother investigating why but switching to XPathDocument worked for me.

like image 22
Rory Avatar answered Oct 14 '22 16:10

Rory