The SQLXML Managed Classes [The main players]
SqlXmlCommand
The SqlXmlCommand class is the SQLXML Managed version of the ADO.NET providers Command classes. It does not however share in common with it's ADO.NET counterparts the derivation from the interface IDbCommand, it inherits directly from the lowest common denominator, namely the object . Despite the apparent curiosity regarding it's object parentage the SqlXmlCommand does provide for running queries against a SQL Server Database and has the ability to return data as a stream or XmlReader . Queries defined inline or in stored procedures can be used along with SQLXML templates, Xpath and annotated schemas. It is also possible to apply xsl stylesheets directly to the SqlXmlCommand object to perform transformations and the SqlXmlCommand can also be used in conjunction with the SqlXmlParameter class in much the same way as with the ADO.NET classes.
Code Listing 4.0
This code snippet outlines an example of using the SqlXmlCommand and returning a XmlReader using it's ExecuteXmlReader method. The code is taken from the Demo Application (see the SQLXMLAUTO Button) and uses the FOR XML AUTO mode.
VB.NETDim coString As String = "Provider=sqloledb;data" & _
"source= diablo;userid=sa;password=mypassword;initial catalog=pubs"
Dim co As New SqlXmlCommand(coString)
Dim xmlRead As XmlReader
Dim ds As New DataSet()
co.RootTag = "Authors"
co.CommandType = SqlXmlCommandType.Sql
co.CommandText = "select * from authors for xml Auto"
xmlRead = co.ExecuteXmlReader
ds.ReadXml(xmlRead)
Me.DataGrid1.DataSource = ds.Tables(0)
C#string coString = "Provider=sqloledb;data source="+
"diablo;userid=sa;password=mypassword;initial catalog=pubs";
SqlXmlCommand co = new SqlXmlCommand(coString);
XmlReader xmlRead = new XmlReader();
DataSet ds = new DataSet();
co.RootTag = "Authors";
co.CommandType = SqlXmlCommandType.Sql;
co.CommandText = "select * from authors for xml Auto";
xmlRead = co.ExecuteXmlReader;
ds.ReadXml(xmlRead);
this.DataGrid1.DataSource = ds.Tables[0];
Harking Back
In the code above you will notice the RootTag property of the SqlXmlCommand class, which is responsible for creating a well formed XML document by placing the tag <Authors>......</Authors> around the incomplete xml returned by the query.
Two more interesting methods of the SqlXmlCommand class are ExecuteToStream and ExecuteStream . ExecuteStream will return the xml data as a stream and ExecuteToStream offers the ability to send the xml returned by the query straight to a "http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemIOFileStreamClassTopic.asp" target=_blank>FileStream for persistence to disk or a "http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketsnetworkstreamclasstopic.asp" target=_blank>NetworkStream .
Client Side and Legacy Applications
The ClientSideXml property of SqlXmlCommand class is particularly useful in cases where the developer is faced with the prospect of developing with legacy code such as stored procedures that that cannot be changed and do not use any of the xml modes to return xml output or the applications architecture demands distributed processing to be performed client side.
Code Listing 5.0
VB.NETDim coString As String="Provider=sqloledb;data"& _
"source=diablo;userid=sa;password=mypassword;initial catalog=pubs"
Dim cmd As New sqlxmlCommand(coString)
Dim xr As XmlReader
Dim xDoc As New XmlDocument()
Dim ds As New DataSet()
cmd.RootTag = "Authors"
cmd.ClientSideXml = True
cmd.CommandText = "exec spAllAuthors for XML nested"
xr = cmd.ExecuteXmlReader()
xDoc.Load(xr)
xDoc.Save("c:\testClientside.xml")
ds.ReadXml("c:\testClientside.xml")
Me.DataGrid1.DataSource = ds
C#string coString = "Provider=sqloledb;data source="+
"diablo;userid=sa;password=mypassword;initial catalog=pubs"
SqlXmlCommand cmd = new SqlXmlCommand(coString);
XmlReader xr;
XmlDocument xDoc = new XmlDocument();
DataSet ds = new DataSet();
cmd.RootTag = "Authors" ;
cmd.ClientSideXml = True;
cmd.CommandText = "exec spAllAuthors for XML nested";
xr = cmd.ExecuteXmlReader();
xDoc.Load(xr);
xDoc.Save("c:\testClientside.xml");
ds.ReadXml("c:\testClientside.xml");
this.DataGrid1.DataSource = ds;
The saving of the output to a file which is consequently read into a DataSet is of no significance other than to demonstrate the possibility and of course it would not be required to save the xml returned from the query to a file in order to use it.
SqlXmlAdapter
The SqlXmlAdapter class is useful in populating DataSet s and making changes to the database by way of XML Diffgram . Just as with a regular DataAdapter the SqlXmlDataAdapter has a Fill method which will populate a DataSet which is set againt the method as an argument. The code in listing 6.0 demonstrates how to use the SqlXmlDataAdapter .
Code Listing 6.0
VB.NETDim coString as String
coString = "Provider=sqloledb;data" & _
"source=diablo;userid=sa;password=mypassword;initial" & _
"catalog=pubs"
Dim cmd As NewSqlXmlCommand(coString)
cmd.RootTag = "Root"
cmd.CommandText = "Authors[@au_lname = ""Stringer""]"
cmd.CommandType = SqlXmlCommandType.XPath
cmd.SchemaPath = "..\AuthorsTitles.xsd"
Dim ds As New DataSet()
Dim ad As New SqlXmlAdapter(cmd)
ad.Fill(ds)
Me.DataGrid1.DataSource = ds
C#string coString = "Provider=sqloledb;data source=diablo;" +
"userid=sa;password=mypassword;initial catalog=pubs"
SqlXmlCommand cmd = new SqlXmlCommand(coString);
cmd.RootTag = "Root";
cmd.CommandText = @"Authors[@au_lname = "Stringer"]";
cmd.CommandType = SqlXmlCommandType.XPath;
cmd.SchemaPath = "..\AuthorsTitles.xsd";
DataSet ds = new DataSet();
SqlXmlAdapter ad = new SqlXmlAdapter(cmd);
ad.Fill(ds);
this.DataGrid1.DataSource = ds;
The above code snippet makes use of an Annotated Schema and an XPath query to return the data from the database and specify a subset (even though here we asked for everything) of the data where a condition is met. The annotated schema code that makes this possible is exhibited below.
Exhibit 5.0
It is important to note on line 3 the declaration of the sql namespace without which this example would not work and be aware that if you create a schema in Visual Studio by dragging a Table from the database onto a new xsd document in your project then line 3 will not be created by VS.NET automatically. If we look at the element 'Authors' declared above this will map directly to the authors table in the pubs database which has been specified as the catalog of the connection string passed as an argument to the instantiated SqlXmlCommand 's constructor. Also worth noting is the SqlXmlCommand 's CommandText property has been used to specify the XPath query.
SQLXML Templates
SQLXML Templates are files that consist of XML, SQL Statements and Parameter declarations. Template files are useful in opening access to the database over http and offer more security than queries executed at the URL. If you are interested in configuring IIS support for SQL Server please take a look at my previous article on the IE Web Controls Treeview and SQLXML. Before we go any further lets look at one.
Exhibit 6.0
The root node must include the reference the namespace above and a <sql:query> element must be nested inside the Node that will act the Document root node. Once this template file has been placed in a virtual directory configured with MMC snap in that comes with the SQLXML 3.0 install, you are free to call this template from the URL like this http://localhost/TreeSqlXml/Template/sqltemplate.xml. I am not going into setting up SQLXML Virtual Directories here, as I stated previously check out the link to my previous article which also includes some worth while links to some other quite useful tutorials on configuring and using SQLXML. Please NOTE that the 'Template' Buttons code in the Demo Application will fail if you don't configure SQLXML 3.0 support for IIS correctly and use the provided sql script "Build Database.sql" in the download. Making use of the template file using the Managed Classes turns out to be quite simple as outlined here in listing 8.0.
Code Listing 7.0
VB.NETDim xmlPath as String
xmlPath = "http://localhost/Treesqlxml/template/sqlTemplate.xml"
Dim ds as New DataSet()
ds.ReadXml(xmlPath , XmlReadMode.InferSchema)
C# string xmlPath = @"http://localhost/Treesqlxml/template/template.sql";
DataSet ds = new DataSet();
ds.ReadXml(xmlPath, XmlReadMode.InferSchema);
If you do happen to set up a template file here is what comes back from calling it via the URL.
SqlXmlParameter
The SqlXml Managed Classes (like their ADO.Net counterparts) provide a Parameter class namely SqlXmlParameter. This class is used widely to pass values to stored procedures and inline sql queries where the query is required to behave in a dynamic manner. The code listing below assumes the xAdp (SqlXmlDataAdapter) and xDs (DataSet) variables are declared with scope to the entire class.
Code Listing 9.0
VB.NETDim coString as String
coString = "Provider=sqloledb;datasource=tpol;" & _
"userid=sa;password=mypassword;initial catalog=pubs"
Dim cmd As New SqlXmlCommand(coString)
Dim param As SqlXmlParameter
xAdp = New SqlXmlAdapter(cmd)
xDs = New DataSet()
cmd.RootTag = "Authors"
cmd.CommandType = SqlXmlCommandType.Sql
cmd.CommandText = "select * from authors where au_lname = ? for xml auto"
param = cmd.CreateParameter
param.Value = Me.ListBox1.SelectedItem
xAdp.Fill(xDs)
Me.DataGrid1.DataSource = xDs
C# string coString = "Provider=sqloledb;;datasource=tpol;" +
"userid=sa;password=mypassword;initial catalog=pubs"
SqlXmlCommand cmd = new SqlXmlCommand(coString);
SqlXmlParameter param;
xAdp = New SqlXmlAdapter(cmd);
xDs = New DataSet();
cmd.RootTag = "Authors";
cmd.CommandType = SqlXmlCommandType.Sql;
cmd.CommandText = "select * from authors where au_lname = ? for xml auto";
param = cmd.CreateParameter;
param.Value = this.ListBox1.SelectedItem;
xAdp.Fill(xDs);
this.DataGrid1.DataSource = xDs;
In Summary
The SqlXml 3.0 Managed Classes give .NET developers the ability to write code that leverages the SQLXML features available in SQL Server. The goal of this article is to provide a platform for beginning to use the FOR XML modes and the Managed Classes, particularly if you happen to have a lot of SQLXML code around the place would like to start using it in a .NET environment.
Final Note:
Much of the managed .NET code listed here is based around templates found in the whitepaper by Scott Swiggart (thanks Scott) which is available with the SQLXML 3.0 download. The project download is available in VB.NET and C#, however the non SqlXml 3.0 examples are only contained in the VB.NET project. Please remember to install the SqlXml 3.0 package and change all the connection strings accordingly before running the demo project otherwise it wont work. For those considering SQLXML not just from a .NET perspective and wish to start experimenting with it I can recommend the Microsoft Press book to which there are links in this article. |
|