The XML data type implements a limited subset of the XQuery specification and a T-SQL query can use XQuery to retrieve information from XML columns or variables.. Static type checking is
Trang 1creating tables with XML columns, and allows declaring XML variables and using them as parameters
and return values
XQuery is a W3C-recommended language created to query and format XML documents XQuery can
be used to query XML documents just like a SQL query is used to retrieve information from relational
tables The XML data type implements a limited subset of the XQuery specification and a T-SQL query
can use XQuery to retrieve information from XML columns or variables
XQuery is built into the Relational Engine of SQL Server, and the Query Optimizer can build query
plans that contain relational query operations as well as XQuery operations Results of XQuery
opera-tions can be joined with relational data, or relational data can be joined with XQuery results SQL Server
supports creating special types of indexes on XML columns to optimize XQuery operations
XML Schema Definition (XSD) is another W3C-recommended language created for describing and
vali-dating XML documents XSD supports creating very powerful and complex validation rules that can be
applied to XML documents to verify that they are fully compliant with the business requirements The
XML data type supports XSD validation and is explained later in this chapter
The XML data type supports a number of methods, listed here:
■ modify()
Each of these methods is explained in detail later in this chapter
Typed and untyped XML
As mentioned earlier, support for XSD schema validation is implemented in SQL Server in the form
of XML schema collections An XML schema collection can be created from an XML schema definition
XML columns or variables can be bound to an XML schema collection An XML column or variable that
is bound to an XML schema collection is known as typed XML
When a typed XML value is modified, SQL Server validates the new value against the rules defined in
the XML schema collection The assignment or modification operation will succeed only if the new value
passes the validations defined in the XML schema collection
Typed XML has a number of advantages over untyped XML columns or variables The most important
benefit is that the validation constraints are always respected The content of a typed XML document is
always valid as per the schema with which it is associated
With typed XML, SQL Server has better knowledge of the XML document (structure, data types, and
so on) and can generate a more optimized query plan Because SQL Server has complete knowledge of
the data types of elements and attributes, storage of typed XML can be made significantly more compact
than untyped XML
Static type checking is possible with typed XML documents, and SQL Server can detect, at compile time,
if an XQuery expression on a typed XML document is mistyped Stored procedures or functions that
Trang 2accept typed XML parameters are protected from receiving invalid XML documents, as SQL Server will
perform implicit validation of the XML value against the schema collection before accepting the
parame-ter value
Creating and using XML columns
The XML data type can be used like other native SQL Server data types in most cases (Note that there
are exceptions, however For example, an XML column cannot be added as a column to a regular index
or used in a comparison operation.) A table can be created with one or more XML columns, or XML
columns can be added to an existing table.VARCHAR/NVARCHAR/VARBINARY/TEXT/NTEXTcolumns
can be altered to XML data type columns if all the existing values are well-formed XML values
Entire XML documents can be retrieved as part of aSELECTquery, or specific information can be
extracted from within the XML documents The following example shows aSELECTquery that selects a
column from a table and a value from the XML document stored in each row:
DECLARE @t TABLE (OrderID INT,OrderData XML )
INSERT INTO @t(OrderID, OrderData)
SELECT 1,
‘<CustomerNumber>1001</CustomerNumber>
<Items>
<Item ItemNumber="1001" Quantity="1" Price="950"/>
<Item ItemNumber="1002" Quantity="1" Price="650" />
</Items>’
SELECT
OrderID,
OrderData.value(’CustomerNumber[1]’,’CHAR(4)’) AS CustomerNumber
FROM @t
/*
-
*/
The code might get a little more complex if the query needs to retrieve more than one element from the
XML document stored in each row Such a query needs to generate more than one row against each row
stored in the base table Thenodes()method of the XML data type can be used to obtain an
acces-sor to each element within the XML document The XML element collection returned by thenodes()
method can be joined with the base table using theCROSS APPLYoperator as shown in the following
example:
DECLARE @t TABLE (OrderID INT,OrderData XML )
INSERT INTO @t(OrderID, OrderData)
SELECT 1,
‘<CustomerNumber>1001</CustomerNumber>
<Items>
<Item ItemNumber="1001" Quantity="1" Price="950"/>
Trang 3<Item ItemNumber="1002" Quantity="1" Price="650" />
</Items>’
SELECT OrderID, o.value(’@ItemNumber’,’CHAR(4)’) AS ItemNumber, o.value(’@Quantity’,’INT’) AS Quantity,
o.value(’@Price’,’MONEY’) AS Price FROM @t
CROSS APPLY OrderData.nodes(’/Items/Item’) x(o) /*
- - -
*/
The preceding examples use thevalue()method exposed by the XML data type XML data type
meth-ods are explained in detail later in this section
Declaring and using XML variables
Just like other SQL Server native data types, XML variables can be created and used in T-SQL batches,
stored procedures, functions, and so on The following example demonstrates a few different ways an
XML variable can be declared:
Declare an XML variable DECLARE @x XML
Declare a TYPED XML Variable DECLARE @x XML(CustomerSchema) Declare a TYPED XML DOCUMENT Variable DECLARE @x XML(DOCUMENT CustomerSchema) Declare a TYPED XML CONTENT variable DECLARE @x XML(CONTENT CustomerSchema)
The first example creates an untyped XML variable, and the second example creates a typed one The
third example creates aDOCUMENTtype variable, and the last one creates aCONTENTtype variable
DOCUMENTandCONTENTtypes are explained later in this chapter
There is a slight difference in the way that an XQuery expression needs to be written for an XML
variable versus an XML column While working with an XML variable, the query will always process
only one document at a time However, while working with an XML column, more than one XML
document may be processed in a single batch operation Because of this, theCROSS APPLY
oper-ator is required while running such a query on an XML column (as demonstrated in the previous
example)
Trang 4What follows is the version of the prior query that operates on an XML variable:
DECLARE @x XML
SELECT @x = ‘
<CustomerNumber>1001</CustomerNumber>
<Items>
<Item ItemNumber="1001" Quantity="1" Price="950"/>
<Item ItemNumber="1002" Quantity="1" Price="650" />
</Items>’
SELECT
o.value(’@ItemNumber’,’CHAR(4)’) AS ItemNumber,
o.value(’@Quantity’,’INT’) AS Quantity,
o.value(’@Price’,’MONEY’) AS Price
FROM @x.nodes(’/Items/Item’) x(o)
/*
ItemNumber Quantity Price
- -
*/
An XML variable may be initialized by a static XML string, from another XML orVARCHAR/NVARCHAR/
VARBINARYvariable, from the return value of a function, or from the result of aFOR XMLquery The
following example shows how to initialize an XML variable from the result of aFOR XMLquery:
DECLARE @x XML
SELECT @x = (
SELECT OrderID
FROM OrderHeader
FOR XML AUTO, TYPE)
XML variables can also be initialized from an XML file, as demonstrated later in the section ‘‘Loading
XML Documents from Disk Files.’’
Using XML parameters and return values
Typed and untyped XML parameters can be passed to a stored procedure asINPUTas well asOUTPUT
parameters XML parameters can be used as arguments as well as the return value of scalar functions or
in result columns of table-valued functions
When a function returns an XML data type value, XML data type methods can be directly called on the
return value, as shown in the following example:
Create a function that returns an XML value
CREATE FUNCTION GetOrderInfo(
@OrderID INT
) RETURNS XML
Trang 5AS BEGIN DECLARE @x XML SELECT @x = ( SELECT OrderID, CustomerID FROM OrderHeader
WHERE OrderID = @OrderID FOR XML PATH(’’),ROOT(’OrderInfo’)) RETURN @x
END GO Call the function and invoke the value() method SELECT dbo.GetOrderInfo(1).value(’(OrderInfo/CustomerID)[1]’,’INT’)
AS CustomerID /*
CustomerID -1
*/
Loading/querying XML documents from disk files
The capability to load XML documents from disk files is one of the very interesting XML features
available with SQL Server This is achieved by using theBULKrow set provider forOPENROWSET The
following example shows how to load the content of an XML file into an XML variable:
/*The sample code below assumes that a file named "items.xml"
exists in folder c:\temp with the following content
<Items>
<Item ItemNumber="1001" Quantity="1" Price="950"/>
<Item ItemNumber="1002" Quantity="1" Price="650" />
</Items>
*/
DECLARE @xml XML SELECT
@xml = CAST(bulkcolumn AS XML) FROM OPENROWSET(BULK ‘C:\temp\items.xml’, SINGLE_BLOB) AS x SELECT
x.value(’@ItemNumber’,’CHAR(4)’) AS ItemNumber, x.value(’@Quantity’,’INT’) AS Quantity,
x.value(’@Price’,’MONEY’) AS Price FROM @xml.nodes(’/Items/Item’) i(x)
Trang 6ItemNumber Quantity Price
- -
*/
OPENROWSET(BULK .[filename, option])can even query the data in the file directly without
loading it to a table or variable It can also be used as the source of anINSERT/UPDATEoperation The
following example queries the XML file directly:
SELECT
x.value(’@ItemNumber’,’CHAR(4)’) AS ItemNumber,
x.value(’@Quantity’,’INT’) AS Quantity,
x.value(’@Price’,’MONEY’) AS Price
FROM (
SELECT CAST(bulkcolumn AS XML) AS data
FROM OPENROWSET(BULK ‘C:\temp\items.xml’, SINGLE_BLOB)
AS x
) a
CROSS APPLY data.nodes(’/Items/Item’) i(x)
/*
ItemNumber Quantity Price
- -
*/
To use theOPENROWSET(BULK )option, the user should haveADMINISTRATOR BULK
OPERATIONSpermission
Limitations of the XML data type
Though the XML data type comes with a number of very interesting capabilities, it has a number of
limitations as well However, the limitations are not really ‘‘limiting,’’ considering the extensive set
of functionalities provided by the data type
The stored representation of an XML data type instance cannot exceed 2 GB The term ‘‘stored
represen-tation’’ is important in the preceding statement, because SQL Server converts XML data type values to an
internal structure and stores it This internal representation takes much less space than the textual
rep-resentation of the XML value The following example demonstrates the reduction in size when a value is
stored as an XML data type value:
DECLARE @EmployeeXML XML, @EmployeeText NVARCHAR(500)
SELECT @EmployeeText = ‘
Trang 7<EmployeeName>Jacob</EmployeeName>
<EmployeeName>Steve</EmployeeName>
<EmployeeName>Bob</EmployeeName>
</EmployeeInfo>’
SELECT DATALENGTH(@EmployeeText) AS StringSize /*
StringSize -284
*/
SELECT @EmployeeXML = @EmployeeText SELECT DATALENGTH(@EmployeeXML) AS XMLSize /*
XMLSize -109
*/
The stored representation of the XML data type value is different and much more optimized than the
textual representation and the limit of 2 GB is on the stored representation It indicates that an XML
data type column may be able to store XML documents containing more than 2 * 1024 * 1024 * 1024
VARCHARcharacters
Unlike other data types, XML data type values cannot be sorted or used in a group by expression They
cannot be used in a comparison operation However, they can be used with theIS NULLoperator to
determine if the value isNULL XML data type columns cannot be used in the key of an index They
can only be used in theINCLUDEDcolumn of an index
To facilitate faster querying and searching over XML columns, SQL Server supports a spe-cial type of index called an XML index XML indexes are different from regular indexes and are discussed later in this chapter.
Understanding XML Data Type Methods
The XML data type supports a number of methods that allow various operations on the XML document
The most common operations needed on an XML document might be reading values from elements
or attributes, querying for specific information, or modifying the document by inserting, updating, or
deleting XML elements or attributes The XML data type comes with a number of methods to support all
these operations
Any operation on an XML document is applied on one or more elements or attributes at a
spe-cific location To perform an operation, the location of the spespe-cific element or attribute has to be
specified
Trang 8XPath is used for locating XML elements and attributes within an XML document and navigating
through the XML tree Every element and attribute within an XML document has a unique ‘‘path.’’ For
example:
’<Items>
<ItemNumber>1003</ItemNumber>
<ItemNumber>1004</ItemNumber>
</Items>’
In the preceding example, the path to the firstItemNumberelement is/Items/ItemNumber[1]and
the second is/Items/ItemNumber[2] Each element and attribute within an XML document can be
uniquely identified and processed using an XPath expression
All the XML data type methods accept XPath expressions to specify the target element or attribute on
which the given operation needs to be performed
value()
One of the most useful methods exposed by the XML data type is thevalue()method It is used to
retrieve scalar values from an XML document as a relational column It takes an XQuery expression and
evaluates it to a single node, casts the results to the specified SQL Server data type, and returns the
value Here is an example:
DECLARE @x XML
SELECt @x = ‘<Order OrderID="1" OrderNumber="SO101" />’
SELECT
@x.value(’(Order/@OrderID)[1]’,’INT’) AS OrderID,
@x.value(’(Order/@OrderNumber)[1]’,’CHAR(5)’) AS OrderNumber
/*
*/
Thevalue()method accepts an XPath expression pointing to the element or attribute to read data
from It also specifies the data type of the result column
nodes()
Thenodes()method returns a row set representation of the XML document An XQuery operation can
be performed on each node returned by the nodes() method This is useful when information has to be
retrieved from all the nodes matching a specific expression Here is an example:
DECLARE @x XML
SELECT @x = ‘
Trang 9<ItemNumber>1001</ItemNumber>
<ItemNumber>1002</ItemNumber>
</Items>’
SELECT x.value(’.’,’CHAR(4)’) AS ItemNumber FROM @x.nodes(’/Items/ItemNumber’) o(x) /*
ItemNumber -1001 1002
*/
The preceding query returns an accessor to all theItemNumberelements in the XML document and
applies thevalue()method on each node
Both of the preceding examples demonstrate how to read information from XML variables There is a
slight difference between the way the query has to be written for XML variables and XML columns
That’s because when working with an XML variable, only one XML document is processed at a time; but
when working with an XML column, several XML documents need to be processed in a single batch
This is usually achieved by using theCROSS APPLYoperator The following example is a modified
version of the preceding query that reads information from an XML column:
SELECT OrderID, x.value(’@ItemNumber’,’CHAR(4)’) AS ItemNumber FROM OrderXML
CROSS APPLY ItemData.nodes(’/Order/Item’) o(x) /*
-
*/
TheCROSS APPLYoperator joins each node returned by thenodes()method with the table, and the
value()method reads theItemNumbervalue from each element returned by thenodes()method
exist()
Theexist()method checks whether an element or attribute specified by a given XPath expression
exists in the document The following query uses theexist()method to filter rows that have a
spe-cific item number:
SELECT OrderID
Trang 10FROM OrderXML
WHERE ItemData.exist(’/Order/Item[@ItemNumber = "Z001"]’) = 1
/*
OrderID
-1
*/
Theexist()method returns true (1) if an element or attribute with the specified XPath expression
exists in the XML document
query()
Thequery()method takes an XQuery expression and evaluates it to a list of XML elements that can
be accessed and processed further
This method supports a subset of the XQuery 1.0 specification and allows querying the XML document,
just like a relational database is queried using a SQL query XQuery is very powerful and supports a
number of operators and functions XQuery is discussed later in this chapter under the section
‘‘Under-standing XQuery and FLWOR operations.’’
modify()
Themodify()method is used to perform XML DML operations on an XML document It allows
inserting, updating, or deleting XML elements or attributes within an XML document A detailed
discussion on themodify()method is given later in this chapter in the section ‘‘Performing XML Data
Modification.’’
Joining XML nodes with relational tables
SQL Server has extended the Relational Engine with XQuery capabilities This offers a number of
advantages — for example, the query processor can evaluate relational and XQuery operations in a
single query A single query plan is created with relational and XQuery operations, and results of
a relational query can be joined with XQuery results and vice versa
A T-SQL Developer can take advantage of this and write T-SQL queries that join XML nodes with
rela-tional columns The following code demonstrates a basic example:
SELECT
oh.OrderID,
c.Name AS Customer,
i.ItemDescription AS Item,
x.value(’@Quantity’,’INT’) AS Quantity,
x.value(’@Price’,’MONEY’) AS Price
FROM OrderHeader oh
INNER JOIN OrderXML ox ON
ItemData.value(’(Order/@OrderID)[1]’,’INT’) = oh.OrderID
CROSS APPLY ItemData.nodes(’/Order/Item’) o(x)