SQL Server 2005中,FOR XML 功能新增了根元素和元素名稱的新選項,增強了嵌套ËǶÌ× FOR調用的能力,因此可以構建復雜的層次結構,新增的Ä PATH模式允許定義使用ʹÓà Xp語法進行檢索的 XML 結構,如下面的示例所示
ProductName AS ' ProductName '
FROM Products
FOR XML PATH ( ' Product ' ), ROOT ( ' Products ' )
此次查詢返回如下 XML。
< Products >
< Product ProductID = " 1 " >
< ProductName > Widget </ ProductName >
</ Product >
< Product ProductID = " 2 " >
< ProductName > Sprocket </ ProductName >
</ Product >
</ Products >
除了增強了 SQL Server 2000 中的現有 XML 功能,SQL Server 2005 還添加了一種新的、本地 xml 數據類型,此數據類型能夠用於為 XML 數據創建變量和列,如下面的示例所示。
(OrderID integer PRIMARY KEY ,
OrderDate datetime ,
CustomerID integer ,
OrderNotes xml)
可以使用 xml 數據類型存儲數據庫中的標記文檔或半結構化數據。列和變量可以用於非類型 XML 和類型 XML,其中后者是由 XML 架構定義 (XSD) 架構驗證的。開發人員可以使用 CREATE XML SCHEMA COLLECTION 語句為數據驗證定義架構,如下面的示例所示。
' <?xml version="1.0" encoding="UTF-16"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- schema declarations go here -->
</xs:schema>
創建架構集合后,可以通過引用該架構集合並使用其包含的架構聲明關聯 xml 變量或列,如下面的示例所示。
(OrderID integer PRIMARY KEY ,
OrderDate datetime ,
CustomerID integer ,
OrderNotes xml(ProductSchema))
在插入或更新值時,相關架構集合中的聲明將驗證類型 XML,出於符合或兼容性原因,有可能強制實施 XML 數據結構的業務規則。
xml 數據類型也提供了一些方法,這些方法可以用於在實例中查詢和操縱 XML 數據。例如,可以在 xml 數據類型的實例中使用 query 方法查詢 XML,如下面的示例所示。
set @x =
' <Invoices>
<Invoice>
<Customer>Kim Abercrombie</Customer>
<Items>
<Item ProductID="2" Price="1.99" Quantity="1" />
<Item ProductID="3" Price="2.99" Quantity="2" />
<Item ProductID="5" Price="1.99" Quantity="1" />
</Items>
</Invoice>
<Invoice>
<Customer>Margaret Smith</Customer>
<Items>
<Item ProductID="2" Price="1.99" Quantity="1"/>
</Items>
</Invoice>
</Invoices> '
SELECT @x .query(
' <CustomerList>
{
for $invoice in /Invoices/Invoice
return $invoice/Customer
}
</CustomerList> ' )
這個例子中的查詢使用了用於在文檔中查找每個 Invoice 元素的 XQuery 表達式,並且從每個 Invoice 元素返回包含 Customer 元素的 XML 文檔,如下面的示例所示。
< Customer > Kim Abercrombie </ Customer >
< Customer > Margaret Smith </ Customer >
</ CustomerList >
另一個在 SQL Server 2005 中引入的與 XML 相關的顯著功能是支持 XML 索引。為了增強 XML 的查詢功能,可以為類型 xml 列創建主 XML 索引和輔助XML 索引。主 XML 索引是 XML 實例中所有節點的細化表示,查詢處理器可以使用它快速查找XML 值中的節點。創建主 XML 索引后,可以創建輔助 XML 索引改善特定查詢類型的性能。下面的例子就是創建主 XML 索引和類型 PATH 的輔助 XML 索引,這可以改善使用 XPath 表達式識別 XML 實例中節點的查詢性能。
ON SalesOrders (Notes)
GO
CREATE XML INDEX idx_xml_Path_Notes
ON SalesOrders (Notes)
USING XML INDEX idx_xml_Notes
FOR PATH
GO
SQL Server 2008 中的 XML 功能
在 SQL Server 2000 和 SQL Server 2005 中引入的 XML 功能,在 SQL Server 2008 中得到了進一步增強。SQL Server 2008 中與XML相關的主要增強功能包括:
改進了架構驗證功能
增強了對 XQuery 的支持
增強了執行 XML 數據操作語言 (DML) 插入的功能
本文的其余內容將詳細介紹這些增強功能,並演示如何使用它們在 SQL Server 2008 中實施更好的 XML 解決方案。
XML 架構驗證增強功能
可以通過強制實施與一個或幾個 XSD 架構符合的方法驗證 XML 數據。架構為特定 XML 數據結構定義許可的 XML 元素和屬性,並通常用於確保包括所有所需數據元素的 XML 文檔使用正確的結構。
SQL Server 2005 通過使用 XML 架構集合引入了 XML 數據驗證。一般的方法是通過使用CREATE XML SCHEMA COLLECTION 語句創建一個包含 XML 數據架構規則的架構集合,然后在定義 xml 列或變量時,引用架構集合的名稱,這些 xml 列或變量必須符合架構集合中的架構規則。這樣,SQL Server 就會驗證在架構集合的列或變量中插入或更新的、違反架構聲明的任何數據。
SQL Server 2005 中的 XML 架構支持實現完整的 XML 規范的大子集,並且包含了大多數通用的 XML 驗證場景。SQL Server 2008 擴展了該支持,使其包括以下已經由用戶標識的附加架構驗證要求:
支持 lax 驗證
完全支持dateTime、 time 和 date 驗證,包括時區信息保護
改進了對 union 和 list 類型的支持
Lax 驗證支持
XML 架構通過 any、anyAttribute 和 anyType 聲明支持 XML 文檔中的通配符部分。
< xs:sequence >
< xs:element name = "CustomerName" />
< xs:element name = "OrderTotal" />
< xs: any namespace = "##other" processContents = "skip"
minOccurs = " 0 " maxOccurs = "unbounded" />
</ xs:sequence >
</ xs:complexType >
此架構聲明定義了一個命名為 Order 的 XML 元素,該元素必須包括命名為 CustomerName 和 OrderTotal 的子元素。此外,該元素還可以包含不限數量的其他元素,但這些元素應與 Order 類型屬於不同的命名空間。下面的 XML 顯示了 一個包含使用此架構聲明定義的 Order 元素實例的 XML 文檔。注意:Order 中還包含一個沒有在架構中顯式定義的 shp:Delivery 元素。
xmlns:shp = "http: // adventure - works.com / shipping" >
< Order >
< CustomerName > Graeme Malcolm </ CustomerName >
< OrderTotal > 299.99 </ OrderTotal >
< shp:Delivery > Express </ shp:Delivery >
</ Order >
</ Invoice >
驗證通配符部分依賴於架構定義中通配符部分的 processContents 屬性。在 SQL Server 2005 中,架構可以對any 和 anyAttribute 聲明使用 skip 和 strict 的 processContents 值。在前面的例子中,通配符元素的 processContents 屬性已經設置為 skip,因此沒有嘗試驗證元素的內容。盡管架構集合包括對 shp:Delivery 元素的聲明(例如,定義一個有效傳遞方法列表),但該元素仍然是未驗證的,除非在 Order 元素的通配符聲明中將 processContents 屬性設置為strict。
SQL Server 2008 添加了對第三個驗證選項的支持。通過將通配符部分的 processContents 屬性設置為 lax,可以對任何含有與它們相關架構聲明的元素強制實施驗證,但是忽略任何在架構中未定義的元素。繼續前面的例子,如果將架構中通配符元素聲明的 declaration 屬性設置為 lax,並為 shp:Delivery 元素添加一個聲明,則在 XML 文檔中的 shp:Delivery 元素將被驗證。然而,如果替換 shp:Delivery 元素,則文檔就包含一個在架構中未定義的元素,此元素將被忽略。
此外,XML 架構規范定義了 anyType 聲明,該聲明包含 anyType 內容模式的 lax 處理。SQL Server 2005 不支持 lax 處理,因此 anyType 內容會被嚴格驗證。SQL Server 2008支持 anyType 內容的 lax 處理,因此該內容會被正確驗證。
完全的 xs:dateTime 支持
可以使用ʹÓà 架構中的¼dateTime 數據類型定義日期和時間數據。日期時間數據表達式的格式為2007-08-01T09:30:00:000Z,這表示協調通用時間 (UTC)的 2007 年ê 8月Ô 日上午9點30分,UTC可由 Z看出。其他時區通過與 UTC 之間的時差表示,例如太平洋標准時間(比 UTC 時間晚 8 小時) 2007 年 12 月 25 日 早晨 6 點可以表示為值 2007-12-25T06:00:00:000-8:00。
XML 架構規范將 dateTime、 date 和 time 數據的時區組件定義為可選項。但在SQL Server 2005 中,則必須為 dateTime、time 和 date 數據提供時區。另外,SQL Server 2005 不保留 dateTime 或 time 數據的時區信息,而是將其規范化為 UTC (例如,如果 XML 中包含值2007-12-25T06:00:00:000-8:00,則 SQL Server 2005 將其規范化為2007-12-25T14:00:00:000Z。)SQL Server 2008刪除了這些限制,因此在存儲dateTime、date 或 time 數據時可以省略時區信息,並且提供的任何時區信息都將保留。
Union 和 List 類型
通過使用 XML 架構,可以為允許將值的有限集分配到多值元素和屬性的 XML 數據定義數據類型。例如,可以將限制可能值(可以賦給產品定義中AvaliableSizes 元素的值)列表的sizeListType 類型定義為 S、M 和 L。SQL Server 2005 支持包含這些簡單類型定義和限制的 XML 架構。例如,可以使用 list 類型定義產品的有效大小,如下面的示例所示。
< xs:list >
< xs:simpleType >
< xs:restriction base = "xs:string" >
< xs:enumeration value = "S" />
< xs:enumeration value = "M" />
< xs:enumeration value = "L" />
</ xs:restriction >
</ xs:simpleType >
</ xs:list >
</ xs:simpleType >
這個架構聲明可用於創建一個能夠列出可購買產品中所有大小的元素,該元素列表的值之間用空格隔開,如下面的示例所示:
<AvailableSizes>S M L</AvailableSizes>
然而,如何支持表達產品大小的兩種不同方式呢?例如,假設一個自行車設備零銷商銷售大、中和小號自行車服,同時也銷售自行車,並使用與框架大小(如 18、20、22 和 24)相關的數字區分自行車的尺寸。為了滿足這個需求,SQL Server 2008 添加了包含 list 類型的 union 類型支持,union 類型可用於將多個 LIST 類型定義和限制合並為一個類型。例如,以下 Transact-SQL 代碼創建了一個已定義 productSizeType 類型的XML 架構集合,此 productSizeType 類型中的有效值包含數字大小(18、20、22 和 24)的列表和已命名大小(S、M 和 L)的列表。
N ' <?xml version="1.0" encoding="UTF-16"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="productSizeType">
<xs:union>
<xs:simpleType>
<xs:list>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:enumeration value="18"/>
<xs:enumeration value="20"/>
<xs:enumeration value="22"/>
<xs:enumeration value="24"/>
</xs:restriction>
</xs:simpleType>
</xs:list>
</xs:simpleType>
<xs:simpleType>
<xs:list>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="S"/>
<xs:enumeration value="M"/>
<xs:enumeration value="L"/>
</xs:restriction>
</xs:simpleType>
</xs:list>
</xs:simpleType>
</xs:union>
</xs:simpleType>
</xs:schema> '
有了架構中的這個聲明,基於 productSizeType 的任何元素都能夠包含這兩種列表中的任何一種;下面例子中的兩種產品元素都是 productSizeType 數據類型的有效實例。
< Product >
< ProductName > Road Bike </ ProductName >
< AvailableSizes > 22 24 </ AvailableSizes >
</ Product >
< Product >
< ProductName > Cycling Jersey </ ProductName >
< AvailableSizes > S M L </ AvailableSizes >
</ Product >
</ Catalog >
同樣,SQL Server 2008 也支持包含 union 類型的 list 類型的架構聲明。
XQuery 增強功能
SQL Server 2005 引入了 xml 數據類型,提供了用於對存儲在列或變量中的 XML 數據執行操作的大量方法。可執行的大多數操作都使用 XQuery 語法導航和操縱 XML 數據。SQL Server 2005 支持的 XQuery 語法包括 FLWOR 表達式中的 for、where、order by 和 return 語句,這些語句可用於循環訪問 XML 文檔中的節點,也可用於返回值。
SQL Server 2008 添加了對 let 語句的支持,該語句用於向 XQuery 表達式中的變量賦值,如下面的示例所示:
set @x =
' <Invoices>
<Invoice>
<Customer>Kim Abercrombie</Customer>
<Items>
<Item ProductID="2" Price="1.99" Quantity="1" />
<Item ProductID="3" Price="2.99" Quantity="2" />
<Item ProductID="5" Price="1.99" Quantity="1" />
</Items>
</Invoice>
<Invoice>
<Customer>Margaret Smith</Customer>
<Items>
<Item ProductID="2" Price="1.99" Quantity="1"/>
</Items>
</Invoice>
</Invoices> '
SELECT @x .query(
' <Orders>
{
for $invoice in /Invoices/Invoice
let $count :=count($invoice/Items/Item)
order by $count
return
<Order>
{$invoice/Customer}
<ItemCount>{$count}</ItemCount>
</Order>
}
</Orders> ' )
這個例子返回以下 XML。
< Order >
< Customer > Margaret Smith </ Customer >
< ItemCount > 1 </ ItemCount >
</ Order >
< Order >
< Customer > Kim Abercrombie </ Customer >
< ItemCount > 3 </ ItemCount >
</ Order >
</ Orders >
注意,SQL Server 2008 不允許向結構化的元素賦值。
XML DML 增強功能
與使用 XQuery 表達式對 XML 數據執行操作一樣,xml 數據類型通過其 modify 方法支持insert、replace value of 和 delete 這些 XML DML 表達式。可以使用這些 XML DML 表達式操縱 xml 列或變量中的 XML 數據。
SQL Server 2008 添加了對使用 insert 表達式中的 xml 變量向現有 XML 結構插入 XML 數據的支持。例如,假定一個名稱為 @productList 的 xml 變量包括以下 XML:
< Bike > Mountain Bike </ Bike >
< Bike > Road Bike </ Bike >
</ Products >
可以使用以下代碼向產品列表中插入一個新自行車:
SET @newBike = ' <Bike>Racing Bike</Bike> '
SET @productList .modify
( ' insert sql:variable("@newBike") as last into (/Products)[1] ' )
運行這段代碼后,@productList 變量中會包括以下 XML。
< Bike > Mountain Bike </ Bike >
< Bike > Road Bike </ Bike >
< Bike > Racing Bike </ Bike >
</ Products >