Tải bản đầy đủ - 0 (trang)
9-8. Obtain an XML Document from a SQL Server Query

9-8. Obtain an XML Document from a SQL Server Query

Tải bản đầy đủ - 0trang

CHAPTER 9 ■ DATABASE ACCESS



How It Works

SQL Server 2000 (and later versions) provides direct support for XML. You simply need to add the clause

FOR XML AUTO to the end of a SQL query to indicate that the results should be returned as XML. By

default, the XML representation is not a full XML document. Instead, it simply returns the result of each

record in a separate element, with all the fields as attributes. For example, the query

SELECT CustomerID, CompanyName FROM Customers FOR XML AUTO

returns XML with the following structure:







Alternatively, you can add the ELEMENTS keyword to the end of a query to structure the results using

nested elements rather than attributes. For example, the query

SELECT CustomerID, CompanyName FROM Customers FOR XML AUTO, ELEMENTS

returns XML with the following structure:



ALFKI

Alfreds Futterkiste





ANTON

Antonio Moreno Taquería





GOURL

Gourmet Lanchonetes





■ Tip You can also fine-tune the format in more detail using the FOR XML EXPLICIT syntax. For example, this

allows you to convert some fields to attributes and others to elements. Refer to SQL Server Books Online for more

information.



When the ExecuteXmlReader command returns, the connection cannot be used for any other

commands while XmlReader is open. You should process the results as quickly as possible, and you must

always close XmlReader. Instead of working with XmlReader and accessing the data sequentially, you can

read the XML data into a System.Xml.XmlDocument. This way, all the data is retrieved into memory, and

the database connection can be closed. You can then continue to interact with the XML document.

(Chapter 6 contains numerous examples of how to use the XmlReader and XmlDocument classes.)



449



www.it-ebooks.info



CHAPTER 9 ■ DATABASE ACCESS



The Code

The following example demonstrates how to retrieve results as XML using the FOR XML clause and the

ExecuteXmlReader method:

using

using

using

using



System;

System.Xml;

System.Data;

System.Data.SqlClient;



namespace Apress.VisualCSharpRecipes.Chapter09

{

class Recipe09_08

{

public static void ConnectedExample()

{

// Create a new SqlConnection object.

using (SqlConnection con = new SqlConnection())

{

// Configure the SqlConnection object's connection string.

con.ConnectionString = @"Data Source = .\sqlexpress;" +

"Database = Northwind; Integrated Security=SSPI";

// Create and configure a new command that includes the

// FOR XML AUTO clause.

using (SqlCommand com = con.CreateCommand())

{

com.CommandType = CommandType.Text;

com.CommandText = "SELECT CustomerID, CompanyName" +

" FROM Customers FOR XML AUTO";

// Open the database connection.

con.Open();

// Execute the command and retrieve an XmlReader to access

// the results.

using (XmlReader reader = com.ExecuteXmlReader())

{

while (reader.Read())

{

Console.Write("Element: " + reader.Name);

if (reader.HasAttributes)

{

for (int i = 0; i < reader.AttributeCount; i++)

{

reader.MoveToAttribute(i);

Console.Write(" {0}: {1}",

reader.Name, reader.Value);

}



450



www.it-ebooks.info



CHAPTER 9 ■ DATABASE ACCESS



// Move the XmlReader back to the element node.

reader.MoveToElement();

Console.WriteLine(Environment.NewLine);

}

}

}

}

}

}

public static void DisconnectedExample()

{

XmlDocument doc = new XmlDocument();

// Create a new SqlConnection object.

using (SqlConnection con = new SqlConnection())

{

// Configure the SqlConnection object's connection string.

con.ConnectionString = @"Data Source = .\sqlexpress;" +

"Database = Northwind; Integrated Security=SSPI";

// Create and configure a new command that includes the

// FOR XML AUTO clause.

SqlCommand com = con.CreateCommand();

com.CommandType = CommandType.Text;

com.CommandText =

"SELECT CustomerID, CompanyName FROM Customers FOR XML AUTO";

// Open the database connection.

con.Open();

// Load the XML data into the XmlDocument. Must first create a

// root element into which to place each result row element.

XmlReader reader = com.ExecuteXmlReader();

doc.LoadXml("");

// Create an XmlNode from the next XML element read from the

// reader.

XmlNode newNode = doc.ReadNode(reader);

while (newNode != null)

{

doc.DocumentElement.AppendChild(newNode);

newNode = doc.ReadNode(reader);

}

}

// Process the disconnected XmlDocument.

Console.WriteLine(doc.OuterXml);

}



451



www.it-ebooks.info



CHAPTER 9 ■ DATABASE ACCESS



public static void Main(string[] args)

{

ConnectedExample();

Console.WriteLine(Environment.NewLine);

DisconnectedExample();

Console.WriteLine(Environment.NewLine);

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



9-9. Perform Asynchronous Database Operations Against

SQL Server

Problem

You need to execute a query or command against a SQL Server database as a background task while your

application continues with other processing.



Solution

Use the BeginExecuteNonQuery, BeginExecuteReader, or BeginExecuteXmlReader method of the

System.Data.SqlClient.SqlCommand class to start the database operation as a background task. These

methods all return a System.IAsyncResult object that you can use to determine the operation’s status or

use thread synchronization to wait for completion. Use the IAsyncResult object and the corresponding

EndExecuteNonQuery, EndExecuteReader, or EndExecuteXmlReader method to obtain the result of the

operation.



■ Note Only the SqlCommand class supports the asynchronous operations described in this recipe. The equivalent

command classes for the Oracle, SQL Server CE, ODBC, and OLE DB data providers do not provide this

functionality.



How It Works

You will usually execute operations against databases synchronously, meaning that the calling code

blocks until the operation is complete. Synchronous calls are most common because your code will



452



www.it-ebooks.info



CHAPTER 9 ■ DATABASE ACCESS



usually require the result of the operation before it can continue. However, sometimes it’s useful to

execute a database operation asynchronously, meaning that you start the method in a separate thread

and then continue with other operations.



■ Note To execute asynchronous operations over a System.Data.SqlClient.SqlConnection connection, you

must specify the value Asynchronous Processing=true in its connection string.



The SqlCommand class implements the asynchronous execution pattern similar to that discussed in

recipe 4-2. As with the general asynchronous execution pattern described in recipe 4-2, the arguments of

the asynchronous execution methods (BeginExecuteNonQuery, BeginExecuteReader, and

BeginExecuteXmlReader) are the same as those of the synchronous variants (ExecuteNonQuery,

ExecuteReader, and ExecuteXmlReader), but they take the following two additional arguments to support

asynchronous completion:





A System.AsyncCallback delegate instance that references a method that the

runtime will call when the asynchronous operation completes. The method is

executed in the context of a thread-pool thread. Passing null means that no

method is called and you must use another completion mechanism (discussed

later in this recipe) to determine when the asynchronous operation is complete.







An object reference that the runtime associates with the asynchronous operation.

The asynchronous operation does not use nor have access to this object, but it’s

available to your code when the operation completes, allowing you to associate

useful state information with an asynchronous operation. For example, this object

allows you to map results against initiated operations in situations where you

initiate many asynchronous operations that use a common callback method to

perform completion.



The EndExecuteNonQuery, EndExecuteReader, and EndExecuteXmlReader methods allow you to retrieve

the return value of an operation that was executed asynchronously, but you must first determine when it

has finished. Here are the four techniques for determining if an asynchronous method has finished:





Blocking: This method stops the execution of the current thread until the

asynchronous operation completes execution. In effect, this is much the same as

synchronous execution. However, in this case, you have the flexibility to decide

exactly when your code enters the blocked state, giving you the opportunity to

carry out some additional processing before blocking.







Polling: This method involves repeatedly testing the state of an asynchronous

operation to determine whether it’s complete. This is a very simple technique and

is not particularly efficient from a processing perspective. You should avoid tight

loops that consume processor time. It’s best to put the polling thread to sleep for a

period using Thread.Sleep between completion tests. Because polling involves

maintaining a loop, the actions of the waiting thread are limited, but you can

easily update some kind of progress indicator.



453



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

9-8. Obtain an XML Document from a SQL Server Query

Tải bản đầy đủ ngay(0 tr)

×