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

Hướng dẫn học Microsoft SQL Server 2008 part 52 ppsx

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 (445.38 KB, 10 trang )

Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 472
Part III Beyond Relational
<Orders xmlns=" /><Order CustomerID="1">SO101</Order>
<Order CustomerID="1">SO102</Order>
</Orders>
*/
The following example demonstrates how to generate elements with multiple namespaces:
;WITH XMLNAMESPACES(
‘ AS cust,
‘ AS ord
)
SELECT
OrderNumber AS ‘ord:OrderNumber’,
CustomerID AS ‘cust:CustomerID’
FROM OrderHeader WHERE OrderID = 1
FOR XML PATH(’’),ROOT(’Orders’)
/*
<Orders xmlns:ord=" />xmlns:cust=" /><ord:OrderNumber>SO101</ord:OrderNumber>
<cust:CustomerID>1</cust:CustomerID>
</Orders>
*/
An element can be associated with a namespace by specifying a colonized name as the element name
(a name that contains a namespace name and element name separated by a colon).
WITH XMLNAMESPACES offers a very easy way to generate XML output with namespace declarations.
XML documents can be created with one or more namespace declarations.
Understanding XQuery and FLWOR operations
XQuery is a W3C recommended language created for querying XML documents. In a simplified sense,
one could say that ‘‘XQuery is to XML what SQL is to a relational database.’’
The
query() method of the XML data type implements a subset of XQuery specifications and provides
a very extensive set of functionalities that enables performing a number of interesting operations on XML


documents.
Simple queries
The basic usage of the query() method is to retrieve one or more XML nodes from the given XML
document. The result of the
query() method is always an XML data type value:
SELECT
ItemData.query(’/Order/Item’)
FROM OrderXML
472
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 473
Manipulating XML Data 18
/*
<Item ItemNumber="D001" Quantity="1" Price="900" />
<Item ItemNumber="Z001" Quantity="1" Price="200" />
<Item ItemNumber="D001" Quantity="1" Price="900" />
*/
The query() method takes an XQuery expression that can be customized to locate and retrieve specific
nodes matching a given condition:
SELECT
ItemData.query(’/Order/Item[@ItemNumber="D001"]’)
FROM OrderXML
/*
<Item ItemNumber="D001" Quantity="1" Price="900" />
<Item ItemNumber="D001" Quantity="1" Price="900" />
*/
The result of the query() method can be used as input for other operations, such as the example
given here:
SELECT
OrderID,

ItemData.query(’
count(/Order/Item)
‘).value(’.’,’INT’) AS LineCount
FROM OrderXML
/*
OrderID LineCount

12
21
*/
This example used the XQuery count() method to retrieve the number of Item elements in each row.
The
query() method always returns an XML data type value; hence, the value() method is used to
retrieve an
INT value from it.
FLWOR operation
ThetruepowerofXQuerycomeswiththeFLWOR operation, which is pronounced like ‘‘flower’’ and
stands for
FOR LET WHERE ORDER BY and RETURN.AFLWOR operation enables querying or transform-
ing XML documents. It can be used either to extract specific information from an XML document or to
restructure the XML document and return a completely new XML value.
Abasic
FLWOR query using FOR and RETURN is shown in the following example:
DECLARE @x XML
SELECT @x = ‘
<Items>
<ItemNumber>1003</ItemNumber>
473
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 474

Part III Beyond Relational
<ItemNumber>1004</ItemNumber>
</Items>’
SELECT
@x.query(’
for $item in Items/ItemNumber
return $item ‘)
/*
<ItemNumber>1003</ItemNumber>
<ItemNumber>1004</ItemNumber>
*/
WHERE
and ORDER BY can be specified to filter and sort the output:
DECLARE @x XML
SELECT @x = ‘
<Items>
<ItemNumber>1003</ItemNumber>
<ItemNumber>1004</ItemNumber>
<ItemNumber>1001</ItemNumber>
<ItemNumber>2007</ItemNumber>
<ItemNumber>3009</ItemNumber>
<ItemNumber>4005</ItemNumber>
</Items>’
SELECT
@x.query(’
for $item in Items/ItemNumber
where $item[. < "2000"]
order by $item
return $item ‘)
/*

<ItemNumber>1001</ItemNumber>
<ItemNumber>1003</ItemNumber>
<ItemNumber>1004</ItemNumber>
*/
The WHERE condition in the preceding XQuery expression filters the nodes for ItemNumber less than
2000. The
ORDER BY clause then orders the nodes by ItemNumber.
A
FLWOR operation can be used to completely restructure an XML document, as demonstrated here:
DECLARE @x XML
SELECT @x = ‘
<Item ItemNumber="D001" Quantity="1" Price="900" />
<Item ItemNumber="Z001" Quantity="1" Price="200" />’
474
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 475
Manipulating XML Data 18
SELECT
@x.query(’
for $item in Item
return
<ItemNumber>
{data($item/@ItemNumber)}
</ItemNumber> ‘)
/*
<ItemNumber>D001</ItemNumber>
<ItemNumber>Z001</ItemNumber>
*/
The preceding example transforms the ItemNumber attributes to elements and produces a completely
different XML document. Complex

FLWOR operations can be applied on an XML document to achieve
very complex transformation requirements.
What’s new for XQuery in SQL Server 2008
SQL Server 2008 adds support for the let clause in FLWOR operations. The let clause allows declaring
and using inline variables within the XQuery expression used in a
FLWOR query:
DECLARE @x XML
SELECT @x = ‘
<Item ItemNumber="D001" Quantity="2" Price="900" />
<Item ItemNumber="Z001" Quantity="3" Price="200" />’
SELECT
@x.query(’
for $item in Item
let $itm := $item/@ItemNumber
let $tot := $item/@Quantity * $item/@Price
return
<Item>
<ItemNumber>{data($itm)}</ItemNumber>
<TotalPrice>{data($tot)}</TotalPrice>
</Item>
‘)
/*
<Item>
<ItemNumber>D001</ItemNumber>
<TotalPrice>1800</TotalPrice>
</Item>
<Item>
<ItemNumber>Z001</ItemNumber>
<TotalPrice>600</TotalPrice>
</Item>

*/
475
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 476
Part III Beyond Relational
The XQuery expression in the preceding example declares two inline variables using the let clause:
$itm and $tot. These variables are initialized within the XQuery expression and used to generate cus-
tom XML nodes.
The
let clause reduces the complexity of FLWOR operations by enabling complex expressions to be
translated into variables.
Understanding XQuery Functions
The XQuery specification has defined a number of XQuery functions, many of which have been
implemented by SQL Server. This section briefly examines the XQuery functions supported by SQL
Server 2008.
String functions
String functions are one of the most commonly used set of functions in any language. SQL Server 2008
supports the following XQuery string functions:

string()
■ concat()
■ substring()
■ contains()
■ string-length()
The string() function is a data accessor function that returns the string value from an element or
attribute. The
concat() function joins two string values, and the substring() function returns
a substring from a given value, starting at a specified position and having a specified length. The
string-length() function returns the length of a given string value. Finally, the contains()
function accepts two string values and returns true if the second value is a substring of the first value.

Numeric and aggregate functions
SQL Server 2008 supports the following XQuery aggregate functions. These functions can be used to
perform aggregate operations over the nodes of an XML document:

min()
■ max()
■ count()
■ sum()
■ avg()
476
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 477
Manipulating XML Data 18
Support for the following XQuery numeric functions is implemented in SQL Server 2008:

ceiling()
■ floor()
■ round()
The functionality exposed by each of these functions is self-explanatory. All these functions exist in T-
SQL as well, and the T-SQL versions of these functions provide the same functionality as the XQuery
versions (except that the T-SQL function is applied on relational rows, whereas the XQuery version is
applied on XML nodes).
Other functions
SQL Server 2008 supports a few more XQuery functions that may be less commonly used, but are still
worthamentionhere:
■ Data accessor function:
data()
■ Boolean functions: not(), true(),andfalse()
■ Sequence functions: empty(), distinct-values(),andid()
■ Node functions: number(), local-name(),andnamespace-uri()

■ Context functions: last() and position()
■ QName functions: expanded-QName(), local-name-from-QName() and namespace-
uri-from-QName
■ SQL Server XQuery extension functions: sql:variable() and sql:column()
The XQuery implementation of SQL Server 2008 still does not support user-defined functions (UDFs),
recommended by the XQuery specification. Future versions of SQL Server might add support for
user-defined functions within XQuery expressions, and the addition of XQuery UDFs will provide more
programming power to the T-SQL developer.
Performing XML Data Modification
The modify() method of the XML data type can be used to perform DML operations on XML docu-
ments. It allows performing insert, update, and delete operations on XML variables or columns.
The
insert, replace value of,anddelete instructions are used with the modify() method to
perform
INSERT, UPDATE,andDELETE operations on XML documents. Each of these operations has
its own syntax and is briefly explained in the following sections.
477
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 478
Part III Beyond Relational
Insert operation
A new element or attribute can be inserted into an XML document by using the modify() method
with the
insert command. A basic example demonstrating an insert operation is given here:
DECLARE @x XML
SELECT @x = ‘<SalesOrder OrderNumber="SO101"/>’
DECLARE @CustomerID INT
SELECT @CustomerID = 1
SET @x.modify(’
insert element CustomerID {sql:variable("@CustomerID")}

as last into (SalesOrder)[1]
‘)
SELECT @x
/*
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
</SalesOrder>
*/
Update operation
The modify() method can be used with replace value of command to modify the value of ele-
ments or attributes. The following example changes the value of the
CustomerID element:
DECLARE @x XML
SELECT @x = ‘
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
</SalesOrder>’
DECLARE @CustomerID INT
SELECT @CustomerID = 2
SET @x.modify(’
replace value of (SalesOrder/CustomerID/text())[1]
with sql:variable("@CustomerID")
‘)
SELECT @x
/*
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
</SalesOrder>
*/
478

www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 479
Manipulating XML Data 18
Delete operation
The modify() method can be used with the delete instruction to remove an element or attribute
from a given XML document. The following example deletes the
CustomerID element from the XML
document:
DECLARE @x XML
SELECT @x = ‘
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
</SalesOrder>’
SET @x.modify(’
delete (SalesOrder/CustomerID)[1]
‘)
SELECT @x
/*
<SalesOrder OrderNumber="SO101" />
*/
What’s new for XML DML operations in SQL Server 2008
SQL Server 2005’s implementation of the modify() method does not support XML variables with
the
insert instruction. With SQL Server 2005, it is not possible to insert an XML value into an
XML document. A possible workaround is to cast the XML value to
VARCHAR/NVARCHAR and per-
form an insert operation. However, in such a case, SQL Server will encode the XML tags within the
VARCHAR/NVARCHAR value, which may not be the desired result most of the time.
SQL Server 2008 enhanced the
modify() method to support XML variables with the insert com-

mand. The following code snippet shows an example:
DECLARE @doc XML, @val XML
SELECT @doc = ‘
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
</SalesOrder>’
SELECT @val = ‘
<Items>
<Item ItemNumber="Z001" Quantity="1" Price="900"/>
</Items>’
SET @doc.modify(’
insert sql:variable("@val")
as last into (SalesOrder)[1]
‘)
SELECT @doc
479
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 480
Part III Beyond Relational
/*
<SalesOrder OrderNumber="SO101">
<CustomerID>1</CustomerID>
<Items>
<Item ItemNumber="Z001" Quantity="1" Price="900" />
</Items>
</SalesOrder>
*/
Note that the syntax of the insert command is slightly different when an XML value is being inserted.
Handling Namespaces
XML uses namespaces to disambiguate elements and attributes. If the XML document contains name-

space declarations, then the XQuery expressions for querying or modifying the XML document should
also contain the required namespace declarations to identify and access the correct XML nodes.
The
WITH NAMESPACES directive can be used to declare the XML namespaces and refer to them in the
XQuery expressions following the declaration:
DECLARE @x XML
SELECT @x = ‘
<SalesOrder xmlns=" />xmlns:cust=" /><OrderID>1</OrderID>
<cust:CustomerID>10001</cust:CustomerID>
</SalesOrder>’
;WITH XMLNAMESPACES(
DEFAULT ‘ />‘ AS cust
)
SELECT
@x.value(’(SalesOrder/OrderID)[1]’,’INT’) AS OrderID,
@x.value(’(SalesOrder/cust:CustomerID)[1]’,’INT’) AS CustomerID
/*
OrderID CustomerID

1 10001
*/
The WITH XMLNAMESPACES directive simplifies namespace declaration, as the namespaces can be
declared once and then reused in the XQuery expression that follows the declaration.
480
www.getcoolebook.com
Nielsen c18.tex V4 - 07/21/2009 1:01pm Page 481
Manipulating XML Data 18
Shredding XML Using OPENXML()
OPENXML(), released along with SQL Server 2000, was the first XML shredding function added to SQL
Server.

OPENXML() is very powerful and is the only option available to shred XML documents (from
T-SQL) in SQL Server 2000. SQL Server 2005 added support for XQuery, which is a better choice over
OPENXML() in most cases. SQL Server 2008 enhanced the XQuery functionalities further by adding
support for ‘‘let’’ clause in FLWOR operations.
The following example shows a basic
OPENXML() function call:
DECLARE @hdoc INT
DECLARE @xml VARCHAR(MAX)
SET @xml =’
<SalesOrder OrderNumber="SO101">
<Items>
<Item ItemNumber="D001" Quantity="1" Price="900.0000" />
<Item ItemNumber="Z001" Quantity="1" Price="200.0000" />
</Items>
</SalesOrder>’
Step 1: initialize XML Document Handle
EXEC sp_xml_preparedocument @hdoc OUTPUT, @xml
Step 2: Call OPENXML()
SELECT * FROM OPENXML(@hdoc, ‘/SalesOrder/Items/Item’)
WITH (
OrderNumber CHAR(5) ‘ / /@OrderNumber’,
ItemNumber CHAR(4) ‘@ItemNumber’,
Quantity INT ‘@Quantity’,
Price MONEY ‘@Price’
)
Step 3: Free document handle
exec sp_xml_removedocument @hdoc
/*
OrderNumber ItemNumber Quantity Price


SO101 D001 1 900.00
SO101 Z001 1 200.00
*/
As is apparent from the preceding e xample, a call to OPENXML() is always a three-step process. Before
the function can be called, a document handle for the current XML document should be created and
initialized. This handle should be passed to the
OPENXML() function call as an a rgument. Finally, the
handle has to be released to free system resources used for the operation.
481
www.getcoolebook.com

×