Tải bản đầy đủ (.pdf) (20 trang)

Microsoft SQL Server 2005 Developer’s Guide- P12 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (284.49 KB, 20 trang )

Chapter 6: Developing Database Applications with ADO.NET 219
Here you can see again how the connection object has been passed in at the top
of the routine. DataAdapter, DataSet, and CommandBuilder objects are then created.
The DataSet is then filled inside the Try-Catch loop. The next statement shows
retrieving the last row in the SpecialOffer table into a DataRow object. The
Description field of the DataRow is then set with a new value, which changes the
Table.Rows.RowState property for this row to reflect Modified. The next statement
calls the DataAdapter’s Update method. The Update method determines the
appropriate command to execute from the value of the RowState property; in this
case, it will call the UpdateCommand of the DataAdapter to resolve the changed row
back to the data source.
Delete Using the CommandBuilder
The next example shows deleting a record from the database.
Private Sub DataSetDeleteSql(cn As SqlConnection)
' Create the dataadapter, and commandbuilder
Dim sqlDA As SqlDataAdapter = New SqlDataAdapter( _
"SELECT * FROM Sales.SpecialOffer", cn)
Dim ds = New DataSet()
Dim sqlCB = New SqlCommandBuilder(sqlDA)
Try
' Populate the dataset
sqlDA.Fill(ds, "SpecialOffer")
' Mark the record in the datatable for deletion
Dim sqlDR = ds.Tables("SpecialOffer").Rows( _
ds.Tables("SpecialOffer").Rows.Count - 1)
sqlDR.Delete()
' Delete the record from the database table
sqlDA.Update(ds, "SpecialOffer")
Catch e As Exception
MsgBox(e.Message)
End Try


End Sub
Again you can see the connection object passed into the routine, and the
DataAdapter, DataSet, and CommandBuilder objects being created. Then the
DataSet is filled in the Try-Catch loop. The next statement retrieves the last row
from the SpecialOffer DataTable into a DataRow object. Then the DataRow’s
Delete method is called to delete the row from the DataTable SpecialOffer. In
reality, this does not physically delete the row from the DataTable but instead
sets the Table.Rows.RowState property to Deleted. Next, when the DataAdapter’s
220 Microsoft SQL Server 2005 Developer’s Guide
Update method is called, the DeleteCommand of the DataAdapter will execute
and delete the record from the database. In contrast, if you call the DataTable’s
Remove or RemoveAt method, the row will be physically removed from the
DataTable in the DataSet. If you use the Remove or RemoveAt method and then
call the Update method, the row in the data source will not be deleted, because
the DataAdapter’s Update method determines what action to take from the Table.
Rows.RowState property and all of the remaining rows in the DataTable have
a RowState of Unmodified; therefore, no action will take place at the data source.
Summary
In this chapter, you got a view of how to develop SQL Server database applications
using Visual Basic and ADO.NET. You were introduced to the different ADO.NET
namespaces and given an overall understanding of the functions of the different
classes that compose the ADO.NET architecture.
221
CHAPTER
7
Developing with XML
IN THIS CHAPTER
The XML Data Type
XQuery Support
XML Data Type Methods

XML Indexes
Using the For XML Clause
OPENXML
XML Bulk Load
Native HTTP SOAP Access
Copyright © 2006 by The McGraw-Hill Companies. Click here for terms of use.
222 Microsoft SQL Server 2005 Developer’s Guide
X
ML (Extensible Markup Language) is the lingua franca of computer
languages. XML’s flexible text-based structure enables it to be used for
an incredibly wide array of network tasks, including for data/document
transfer, for Web page rendering, and even as a transport for Web services via
SOAP (Simple Object Access Protocol). Microsoft first added basic support for
XML to SQL Server 2000, by adding the FOR XML clause as part of the SELECT
statement and the OpenXML function. The FOR XML clause allowed a SELECT
statement to return an XML document containing the results, while the OpenXML
function created a rowset over XML contained in one or more columns. To this basic
level, Microsoft’s SQL XML Web release for SQL Server 2000 added support for
UpdateGrams, Templates, and BulkLoad to XML Views, as well as stored procedure
access via Web services and SOAP. However, SQL Server 2000’s support for XML
had some limitations. The XML data needed to be stored in a SQL Server database
using either the Text or Image data type. Once it was stored, there was little that SQL
Server could do with it. SQL Server 2000 was unable to natively query the stored
XML. SQL Server had no checks on the validity of the data, and in order to query
the XML documents, you essentially needed to extract and parse each document on
a one-at-a-time, per-row basis.
SQL Server 2005 builds on this starting point by adding support for many new XML
features. First, SQL Server 2005 provides a new level of unified storage for XML and
relational data by adding a new XML data type. SQL Server 2005’s native XML data
type provides support for both native XML queries using XQuery as well as strong data

typing by associating the XML data type to an XSD (Extensible Schema Definition).
The XML support is tightly integrated with the SQL Server 2005 relational database
engine. SQL Server 2005 provides support for triggers on XML, replication of XML
data, and bulk load of XML data, as well as enhanced support for data access via
SOAP. In this chapter you’ll see how to develop applications that make use of SQL
Server 2005’s native XML support.
The XML Data Type
The XML data type can be used as a column in a table or a variable or parameter in
a stored procedure. It can be used to store both typed and untyped data. If the data
stored in an XML column has no XSD schema, then it is considered untyped. If there
is an associated XSD schema, then SQL Server 2005 will check all data inserted
into the data type against the schema to make sure that the data store complies with
the schema definition. In all cases, SQL Server 2005 checks the data that is stored
in the XML data type to ensure that it is well formed, although partial documents
Chapter 7: Developing with XML 223
are allowed. If you attempt to insert invalid data into the XML data type, SQL
Server 2005 will raise an error and the data will not be stored. The XML data type
can accept a maximum of 2GB of data, and its on-disk storage structure is like the
varbinary(max) data type.
The following listing illustrates creating a simple table that uses the new XML
data type:
CREATE TABLE MyXMLDocs
(DocID INT PRIMARY KEY,
MyXmlDoc XML)
Here the MyXmlDoc column uses the XML data type to specify that the column
will store XML data. You can populate an XML column in the same way that you do
other data types, using either T-SQL or ADO.NET client applications. The following
example shows how you can store a value in an XML column using a T-SQL
INSERT statement:
INSERT INTO MyXmlDocs Values

(1,'<MyXMLDoc>
<DocumentID>1</DocumentID>
<DocumentText>Text</DocumentText>
</MyXMLDoc>')
Data Validation Using an XSD Schema
The native XML data type checks to ensure that any data that’s stored in an XML
variable or column is a valid XML document. On its own, it doesn’t check any
more than that. However, Microsoft designed the XML data type to be able to
support more sophisticated document validation using an XSD schema. When an
XSD schema is defined for an XML data type column, the SQL Server engine will
check to make sure that all of the data stored in the XML column complies with the
definition that’s supplied by the XSD schema.
Creating the XSD Schema
The following listing shows a sample XSD schema for the simple XML document
that was used in the preceding example:
<xs:schema xmlns:xs=" />elementFormDefault="qualified" targetNamespace="MyXMLDocSchema"
xmlns="MyXMLDocSchema">
<xs:element name="MyXMLDoc">
<xs:complexType>
224 Microsoft SQL Server 2005 Developer’s Guide
<xs:sequence>
<xs:element name="DocumentID" type="xs:int" />
<xs:element name="DocumentBody" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This XSD schema uses the namespace of MyXMLDocSchema and defines an
XML document that has a complex element named MyXMLDoc. The MyXMLDoc
complex element contains two simple elements. The first simple element must be

named DocumentID, and a second simple element is named DocumentBody. The
DocumentID element must contain an integer, while the DocumentBody element
must contain XML string-type data.
To create a strongly typed XML column or variable, you first need to register the
XSD schema with SQL Server using the CREATE XML SCHEMA COLLECTION
statement. This registers the schema in the SQL Server database. After the XSD
schema is registered, it can be used by an XML data type. You can see an example of
using the CREATE XML SCHEMA COLLECTION statement in the following listing:
CREATE XML SCHEMA COLLECTION MyXMLDocSchema AS
N'<?xml version="1.0"?>
<xs:schema xmlns:xs=" /> elementFormDefault="qualified" targetNamespace="http://MyXMLDocSchema">
<xs:element name="MyXMLDoc">
<xs:complexType>
<xs:sequence>
<xs:element name="DocumentID" type="xs:int" />
<xs:element name="DocumentBody" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>'
The CREATE XML SCHEMA COLLECTION statement takes a single argument
that names the collection. Next, after the AS clause it expects a valid XSD schema
enclosed in single quotes. If the schema is not valid, an error will be issued when
the statement is executed. The CREATE XML SCHEMA COLLECTION statement
is database specific, and the schema that is registered can be accessed only in the
database for which the schema is registered.
Chapter 7: Developing with XML 225
NOTE
The CREATE XML SCHEMA COLLECTION statement requires that the XSD schema be passed as a
variable. It cannot read the schema in from a disk file.

Once you’ve registered the XML schema with a SQL Server 2005 database, you
can go ahead and associate XML variables and columns with that schema. You
associate the XML data type with the schema when it is first created. Providing the
XML data type with a schema allows SQL Server to check that any XML data that
is placed in that data type will adhere to the definition provided by the associated
schema. The following example illustrates how you can create a table that uses the
MyXMLDocSchema that was created earlier:
CREATE TABLE MyXMLDocs
(DocID INT PRIMARY KEY,
MyXmlDoc XML(MyXMLDocSchema))
NOTE
If you previously created the MyXMLDocs table in your example database, you would need to drop
the table before running this code.
As in the earlier example, the MyXMLDocs table is created using the CREATE
TABLE statement. However, in this example the MyXMLDoc column is created
using an argument that specifies that name of the registered XSD schema definition
named MyXMLDocSchema.
There’s no change to the basic way that you insert data into the typed XML
column. However, once the DocumentBody column has been typed, all of the data
that’s stored there must comply with XSD schema definition. The following listing
shows how you can use an INSERT statement to add data to the MyXMLDoc
column:
INSERT INTO MyXMLDocs (DocID, MyXMLDoc)Values
(1,'<MyXMLDoc xmlns="http://MyXMLDocSchema">
<DocumentID>1</DocumentID>
<DocumentBody>"My text"</DocumentBody>
</MyXMLDoc>')
The value for the DocID column is a standard integer data type of 1. The XML
data that’s inserted into the MyXMLDoc column must comply with the MyXMLDoc
Schema. The XML document must reference the associated XML namespace http://

MyXMLDocSchema. It must also possess a complex element named MyXMLDoc,
226 Microsoft SQL Server 2005 Developer’s Guide
which in turn contains the DocumentID and DocumentBody elements. The SQL
Server engine will raise an error if you attempt to insert any other XML document
into the MyXMLDocs column. For example, the code in the following listing
attempts to insert a row that contains XML data that doesn’t comply with the
MyXMLDocSchema:
INSERT INTO MyXmlDocs (DocID, MyXMLDoc) Values
(3,'<root>empty</root>')
Because the data does not conform to the associated XSD schema, SQL Server
will return an error message like the one shown in the following listing:
Msg 6913, Level 16, State 1, Line 1
XML Validation: Declaration not found for element 'root'.
Location: /*:root[1]
NOTE
As you might expect from their dependent relationship, if you assign a schema to a column in
a table, that table must be altered or dropped before that schema definition can be updated.
Retrieving a Registered XML Schema
Once you import a schema using CREATE XML SCHEMA COLLECTION, the
schema components are stored by SQL Server. The stored schema can be listed
by querying the sys.xml_schema_collections system view, as you can see in the
following example:
SELECT * FROM sys.xml_schema_collections
The sys.xml_schema_collections view is database specific. This statement will
return a result set showing all of the registered schemas in a database like the one
that follows:
xml_collection_id schema_id principal_id name


1 4 NULL sys

65537 1 NULL MyXMLDocSchema
(2 row(s) affected)
Chapter 7: Developing with XML 227
You can also use the new XML_SCHEMA_NAMESPACE function to
retrieve the XML schema. The following listing illustrates retrieving the
MyXMLDocSchema schema.
SELECT XML_SCHEMA_NAMESPACE(N'dbo',N'MyXMLDocSchema')
This statement will return a result set showing the registered schema, as you can
see here:
<xsd:schema xmlns:xsd= />xmlns:t="http://MyXMLDocSchema" targetNamespace="http://MyXMLDocSchema"
elementFormDefault="qualified">
<xsd:element name="MyXMLDoc">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:sequence>
<xsd:element name="DocumentID" type="xsd:int" />
<xsd:element name="DocumentBody" type="xsd:string" />
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
NOTE
Executing this script with SQL Server Management Studio’s Query Editor returns a grid with
a single column containing a hyperlink. Clicking the hyperlink displays the XSD in the XML Editor,
which displays the result that you can see in the preceding listing.
XQuery Support
In the preceding section you saw how XQuery is used in the new XML data type’s

methods. XQuery is based on the XPath language created by the W3C (www.w3c.org)
for querying XML data. XQuery extends the XPath language by adding the ability to
update data as well as support for better iteration and sorting of results. T-SQL supports
a subset of the XQuery language that is used for querying the XML data type. One of
the coolest things about SQL Server’s XQuery support is the tight integration it has
with the relational engine. XQuery is closely integrated with T-SQL, and the XML
228 Microsoft SQL Server 2005 Developer’s Guide
queries are not restricted to the contents of a single XML row but instead can cross
multiple rows exactly like relational queries, without the need to extract and parse the
XML for each row.
A description of the XQuery language is beyond the scope of this book, but this
section will show you some of the basics for getting started using XQuery to query
SQL Server’s XML data type.
Querying Element Data
XQuery is a flexible query language that’s well suited to querying XML documents
that have a hierarchical structure. In this section you’ll learn about the basics of
using XQuery in conjunction with T-SQL to query the data store in SQL Server
2005’s XML data type.
Querying Multiple Elements
XQuery can return the result from one XML node or multiple nodes. The following
example illustrates returning all of the subelements and their values:
DECLARE @x xml
SET @x = '<Myroot><Element1>One</Element1><Element2>Two</Element2></Myroot>'
SELECT @x.query('/Myroot')
Here the new variable @x of the XML data type is populated using the SET
statement and has the following structure:
<Myroot>
<Element1>One</Element1>
<Element2>Two</Element2>
</Myroot>

The XQuery is executed using the XML data type’s Query method. (More
information about the XML data type methods is presented in the following section.)
The XQuery itself basically requests all of the nodes that are children of the /Myroot
node. You can see the results in the following listing:

<Myroot><Element1>One</Element1><Element2>Two</Element2></Myroot>
(1 row(s) affected)
Chapter 7: Developing with XML 229
Querying a Single Element
The preceding example showed how to query all of the nodes from a parent node.
This example illustrates querying a single node:
DECLARE @x xml
SET @x = '<Myroot><Element1>One</Element1><Element2>Two</Element2></Myroot>'
SELECT @x.query('/Myroot/Element1')
Each level in the XML document hierarchy is closed by the / symbol. Here the
XQuery returns the value of just the Element1 node, as is shown in the following
listing:

<Element1>One</Element1>
(1 row(s) affected)
Querying Single Element Values
Unlike T-SQL, XQuery also has the capability to query for single sets of node values
according to their predicate or position in the set. The following listing shows how to
retrieve the first value from the Element2 node:
DECLARE @x xml
SET @x = '<Myroot><Element1>One</Element1><Element2>Two</Element2></Myroot>'
SELECT @x.query('(/Myroot/Element2)[1]')
In this example the hierarchy of nodes is placed within parenthesis. The desired
node number follows enclosed in brackets. You can see the results in the following
listing:


<Element2>Two</Element2>
(1 row(s) affected)
Querying Typed XML
Typed XML (i.e., XML that has an associated schema) requires that you declare the
appropriate namespace in order to retrieve the nodes from the XML document. The
following listing illustrates an XQuery that queries the sample MyXMLDocs table
230 Microsoft SQL Server 2005 Developer’s Guide
that was used in the earlier examples. The MyXMLDoc column in this table contains
typed XML.
SELECT MyXMLDoc.query('declare namespace tns="http://MyXMLDocSchema";
/tns:MyXMLDoc/ ') As MyXMLBody
FROM MyXMLDocs
The declare namespace directive creates a namespace named tns and assigns
that namespace the value of http://MyXMLDocSchema. This value must match the
namespace from the schema. The XQuery needs to preface the node names with the
namespace. You can see the results in the following listing:

<MyXMLDoc xmlns="http://MyXMLDocSchema"><DocumentID>1</DocumentID>
<DocumentBody>Modified Body</DocumentBody></MyXMLDoc>
<MyXMLDoc xmlns="http://MyXMLDocSchema"><DocumentID>2</DocumentID>
<DocumentBody>"My text2"</DocumentBody></MyXMLDoc>
(2 row(s) affected)
FLWR (For-Let-Where-Return)
The XPath-style queries work well for standard queries. However, they aren’t as
flexible as T-SQL. The FLWR (For-Let-Where-Return) statement adds a level
of flexibility to SQL Server’s XQuery implementation. In SQL Server 2005, the
Let clause is not supported but the For, Order By, Where, and Return clauses are
supported. In addition, the FLWR syntax looks more like T-SQL and is probably
more readily usable for experienced T-SQL coders. You can see an example of using

the FLWR query in the following listing:
SELECT MyXMLDoc.query
('declare namespace tns="http://MyXMLDocSchema";
for $db in /tns:MyXMLDoc
where /tns:MyXMLDoc/tns:DocumentID = 1
return $db')
FROM MyXMLDocs
This code uses the example MyXMLDocs table that was created earlier in this
chapter. Because the MyXMLDoc column has an attached schema, a namespace
must be declared at the top of the XQuery. Like the SQL SELECT clause the FOR
clause is used to tell the query where to look for data. The WHERE clause restricts
Chapter 7: Developing with XML 231
the result set. The RETURN clause specifies the data that will be returned. Here, the
XQuery looks in the document MyXMLDoc for elements where the DocumentID
element is equal to the value of 1. You can see the results in the following listing:

<MyXMLDoc xmlns="http://MyXMLDocSchema"><DocumentID>1</DocumentID>
<DocumentBody>Modified Body</DocumentBody></MyXMLDoc>
(3 row(s) affected)
This section presented some of the basics about XQuery; the topic is definitively
large enough to be covered in its own book. For more details about the W3C XQuery
standard, you can refer to and />TR/2004/WD-xquery-20040723/. The SQL Server 2005 Books Online also has an
introduction to the XQuery language.
XML Data Type Methods
SQL Server 2005 provides several new built-in methods for working with the XML
data type. Unlike standard relational data, XML data is usually hierarchical, complete
with structures and metadata, and in order to provide true XML integration, SQL
Server needed a way to seamlessly access the data stored in an XML document. The
XML data type’s built-in methods enable you to drill down into the content of XML
documents that are stored using the XML data type. This section will show you how to

use the XML data type’s methods.
Exist(XQuery)
The XML data type’s Exists method enables you to check the contents of an XML
document for the existence of elements or attributes using an XQuery expression.
The Exists method takes one parameter that consists of a XQuery statement and
returns the following values:
Return Value Description
0 The node was not found (FALSE).
1 The node exists (TRUE).
Null The XML data type was null.
232 Microsoft SQL Server 2005 Developer’s Guide
The following listing shows how to use the XML data type’s Exist method:
SELECT * FROM MyXMLDocs
WHERE MyXmlDoc.exist('declare namespace tns="http://MyXMLDocSchema";
/tns:MyXMLDoc/tns:DocumentID=1') = 1
The first parameter of the XML Exist method is required and takes an XQuery
expression. Here the XQuery tests for a DocumentID element equal to a value of
1. A namespace is declared because the MyXMLDoc column is typed—meaning
it has an associated schema. The Exist method can return the value of TRUE (1) if
the XQuery expression returns an XML node, FALSE (0) if the expression doesn’t
return a node, or NULL if the XML data type instance is null. Using the XML data
from the previous examples, you can see the results of the XML Exist method here:
DocID MyXmlDoc

1 <MyXMLDoc xmlns="http://MyXMLDocSchema">
<DocumentID>1</DocumentID>
<DocumentBody>"My text"</DocumentBody></MyXMLDoc>
(1 row(s) affected)
NOTE
The preceding listing was reformatted to make it more readable in the published page width.

Modify(XML DML)
While the previous examples illustrated how to use XQuery to retrieve information
from an XML document, XQuery can also be used for deleting, inserting, and
updating part of an XML document. The Modify method enables you to modify
a stored XML document. You can use the Modify method either to update the entire
XML document or to update just a selected part of the document. You can see an
example of using the Modify method in the following listing:
UPDATE MyXMLDocs
SET MyXMLDoc.modify('declare namespace tns="http://MyXMLDocSchema";
replace value of (/tns:MyXMLDoc/tns:DocumentBody)[1] with
"Modified Body"') WHERE DocID = 1
The XML data type’s Modify method uses an XML Data Modification Language
(XML DML) statement as its parameter. XML DML is a Microsoft extension to the
XQuery language that enables modification of XML documents. The Modify method
supports the Insert, Delete, and Replace values of XML DML statements. In addition,
Chapter 7: Developing with XML 233
the Modify method can be used only in the SET clause of an UPDATE statement. In
this example, since the MyXMLDoc XML column is typed, the XML DML statement
must specify the namespace for the schema. Next, you can see where the Replace
value of the XML DML command is used to replace the value of the DocumentBody
element with the new value of “Modified Body” for the row where the DocID column
is equal to 1. The [1] notation indicates that the operation is for a single value.
NOTE
While this example illustrates performing a replace operation, the Modify method also supports
insert and delete operations, allowing the addition of new elements and the deletion of existing
elements.
Once the previous Modify method has been executed, you can run the following
SELECT statement to see the updated values:
Select MyXMLDoc from MyXM#LDocs
Given the earlier insert example, this statement would produce the following

result, where you can see the updated value in the DocumentBody element:
MyXMLDoc
<MyXMLDoc
xmlns="http://MyXMLDocSchema"><DocumentID>1</DocumentID>
<DocumentBody>Modified Body</DocumentBody></MyXMLDoc>
(1 row(s) affected)
Query(XQuery)
The XML data type’s Query method can retrieve either the entire contents of an
XML document or selected sections of the XML document. The Query method
accepts an XQuery statement as a parameter. You can see an example of using the
Query method in the following listing:
SELECT DocID, MyXMLDoc.query('declare namespace tns="http://MyXMLDocSchema";
/tns:MyXMLDoc/tns:DocumentBody') AS Body
FROM MyXMLDocs
This XQuery expression returns the values from the XML document’s
DocumentBody element. Again, the namespace is specified because the MyXMLDoc
XML data type has an associated schema, named MyXMLDocSchema. In this
234 Microsoft SQL Server 2005 Developer’s Guide
example, you can see how SQL Server 2005 easily integrates relational column
data with XML data. Here, DocID comes from a relational column, while the
DocumentBody element is queried out of the XML column. The following listing
shows the results of the XQuery:
DocID Body

1 <tns:DocumentBody xmlns:tns="http://MyXMLDocSchema">
Modified Body</tns:DocumentBody>
2 <tns:DocumentBody xmlns:tns="http://MyXMLDocSchema">
"My text2"</tns:DocumentBody>
(2 row(s) affected)
NOTE

The preceding listing was reformatted to make it more readable in the published page width.
Value(XQuery, [node ref])
The Value method enables the extraction of scalar values from an XML data type.
You can see an example of how the XML data type’s Value method is used in the
following listing:
SELECT MyXMLDoc.value('declare namespace xd="http://MyXMLDocSchema";
(/xd:MyXMLDoc/xd:DocumentID)[1]', 'int') AS ID
FROM MyXMLDocs
Unlike the other XML data type methods, the XML Value method requires two
parameters. The first parameter is an XQuery expression, and the second parameter
specifies the SQL data type that will hold the scalar value returned by the Value
method. This example returns all of the values contained in the DocumentID element
and converts them to the int data type, as shown in the following results:
ID

1
2
(2 row(s) affected)
Chapter 7: Developing with XML 235
XML Indexes
The XML data type supports a maximum of 2GB of storage, which is quite large.
The size of the XML data and its usage can have a big impact on the performance
the system can achieve when querying XML data. To improve the performance
of XML queries, SQL Server 2005 provides the ability to create indexes over the
columns that have the XML data type.
Primary XML Indexes
In order to create an XML index on an XML data type column, a clustered primary
key must exist for the table. In addition, if you need to change the primary key
for the table, you must first delete the XML index. An XML index covers all the
elements in the XML column, and you can have only one XML index per column.

An XML index cannot have the same name as an existing index. XML indexes can
be created only on XML data types in a table. They cannot be created on columns in
views or on XML data type variables. A primary XML index consists of a persistent
shredded representation of the data in the XML column. The following shows an
example of how to create a primary XML index on the MyXMLDocs table that was
used in the earlier examples:
CREATE PRIMARY XML INDEX MyXMLDocsIdx ON MyXMLDocs(MyXMLDoc)
This example shows the creation of a primary XML index named MyXMLDocsIdx.
This index is created on the MyXMLDoc XML data type column in the MyXMLDocs
table. Just like regular SQL Server indexes, XML indexes can be viewed by querying
the sys.indexes view.
Secondary XML Indexes
In addition to the primary index, you can also build secondary XML indexes. SQL
Server 2005 supports the following secondary XML indexes:
Secondary index type Description
Path The document path is used to build the index.
Value The document values are used to build the index.
Property The document’s properties are used to build the index.
236 Microsoft SQL Server 2005 Developer’s Guide
Secondary indexes are always partitioned in the same way as the primary XML
index. The following listing shows the creation of a secondary-path XML index:
CREATE XML INDEX My2ndXMLDocsIdx ON MyXMLDocs(MyXMLDoc)
USING XML INDEX MyXMLDocsIdx FOR PATH
Using the For XML Clause
The FOR XML clause was first added to the T-SQL SELECT clause with SQL
Server 2000. The For XML clause enables SQL Server to return XML results from
a query. In this section you first learn about the preexisting FOR XML Raw, Auto,
and Explicit support. Next you’ll see how to use some of the new capabilities that
are found in SQL Server 2005, including support for the XML data type via a new
Type mode, added support for result shaping using the PATH mode, nested FOR

XML queries, and inline XSD schema generation.
For XML Raw
The For XML Raw mode returns a result set where each result row is returned in
an element named using a generic identifier for the row. The value of each column
is returned using attribute pairs. This form typically is used where some other
applications will provide additional processing of the data. However, an external,
B2B-type transfer will typically require the use of more descriptive tags and a more
flexible structure. The For XML Raw results are essentially the XML equivalent of
CSV (Command Separated Value) files. The following listing presents an example of
using the For XML Raw mode:
SELECT Top 3 title, FirstName, LastName from Person.Contact FOR XML RAW
XML_F52E2B61-18A1-11d1-B105-00805F49916B

<row title="Mr." FirstName="Gustavo" LastName="Achong"/>
<row title="Ms." FirstName="Catherine" LastName="Abel"/>
<row title="Ms." FirstName="Kim" LastName="Abercrombie"/>
(5 row(s) affected)
NOTE
The T-SQL code in the preceding listing is designed to work with Person.Contact table in the
AdventureWorks sample database.
Chapter 7: Developing with XML 237
For XML Auto
The For XML Auto mode provides more flexibility in terms of the tags that are
returned by a SQL statement. However, it is still limited in the structure of the
XML results that are generated. By default, the SQL Server Table or View name
is used as the element name, and column names are used as the attributes for each
element. You can use the Elements directive to specify that each column is made
into a child element.
Nesting of elements is controlled by the order of the columns used in the Select
statement. While the results of Auto mode won’t produce XML documents that

conform to industry standards, they do support loosely coupled systems and can be
used for simple B2B transfers. The following listing presents an example of using
the For XML Auto mode:
SELECT Top 3 title, FirstName, LastName from Person.Contact FOR XML AUTO
XML_F52E2B61-18A1-11d1-B105-00805F49916B

<Person.Contact title="Mr." FirstName="Gustavo" LastName="Achong"/>
<Person.Contact title="Ms." FirstName="Catherine" LastName="Abel"/>
<Person.Contact title="Ms." FirstName="Kim" LastName="Abercrombie"/>
(3 row(s) affected)
For XML Explicit
The For XML Explicit mode produces the most flexible results and can be used to
meet complex requirements. Explicit mode affords you complete control over the
names of the tags and the hierarchy and nesting of the elements produced. Columns
can be individually mapped to various elements or attributes. However, the For
Explicit mode requires the use of complex SQL queries that must specify the structure
of a universal table that describes the desired XML document. The syntax required
by Explicit mode is demanding, and it’s up to you to make sure that the XML that’s
generated is well formed and valid. Explicit mode’s flexibility allows it to meet the
needs for many industry-standard message specifications.
The EXPLICIT mode is implemented through UNION ALL queries, which
essentially combine results of two or more queries. Each query must contain the
same number of columns, and the corresponding columns in each query need to have
compatible data types. The XML hierarchy is defined by the top or parent query.
238 Microsoft SQL Server 2005 Developer’s Guide
The subsequent queries retrieve data for each of the XML nodes. The following
listing shows an example of using the FOR XML EXPLICT mode:
SELECT Top 3
1 as Tag, NULL as Parent,
EmployeeID as [Employee!1!Employee_ID],

NULL as [Name!2!Last_Name!ELEMENT],
NULL as [Name!2!First_Name!ELEMENT]
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
UNION ALL
SELECT Top 3
2 as Tag, 1 as Parent,
EmployeeID,
LastName,
FirstName
FROM HumanResources.Employee E, Person.Contact C
WHERE E.ContactID = C.ContactID
ORDER BY [Employee!1!Employee_ID]
FOR XML EXPLICIT
This query describes a two-level hierarchy. The first query retrieves the values
for the Employee element, and the second query retrieves the values for the Name
element. The Top 3 clause is simply used to limit the size of the result set. In the first
query you’ll notice the ELEMENT directive is used to specify that the results are
output as XML elements rather than attributes. The values prior to the ELEMENT
directive state the parent element’s name, the element level, and finally the element
name that will be created.
As you can see in the following listing, the FOR XML EXCPLICIT mode gives
you more control over the output of the query; however, you pay the price of added
complexity:
<Employee Employee_ID="1">
<Name>
<Last_Name>Gilbert</Last_Name>
<First_Name>Guy</First_Name>
</Name>
</Employee>

<Employee Employee_ID="2">

×