技术开发 频道

SQL Server 2008中XML的新增功能

【IT168 技术文档】
SQL Server 2008 中 XML 的新增功能
SQL Server 技术文章

作者:Graeme Malcolm(内容主管)
技术审查:Dragan Tomic 和 Michael Rys
项目编辑:Joanne Hodgins


发布日期:2008 年 8 月
适用产品:SQL Server 2008

摘要:Microsoft® SQL Server™ 2008 通过增强对 XML 架构验证和 XQuery 的支持及增加 xml 数据类型,构建对 XML 的广泛支持。

版权

这是一份预备文档,在本文档中所述软件的最终商业版本发布之前,该文档的内容可能会发生重大变化。

本文档中提供的信息代表了 Microsoft Corporation 当前(软件发布之前)对所讨论问题持有的观点。因为 Microsoft 必须响应不断变化的市场条件,所以其当前的观点不应被解释为是一种承诺,软件发布之后,Microsoft 不能保证现在所提供的所有信息准确无误。

这份白皮书仅供参考。Microsoft 对本文档中提供的信息不做任何担保、明示、暗示或法律方面的承诺。

用户有责任遵守所有适用的版权法。在版权权利限制下,未经 Microsoft 公司明确的书面许可,本文档的任何内容不能被复制、存储或放进检索系统,或者以任何形式或任何手段(电子、机械、复印、录制或其他)或为达到任何目的进行转换。

Microsoft对本文档涵盖的主题内容可能拥有专利、专利申请、商标、版权或其他知识产权。没有来自Microsoft的任何书面许可协议的明确表示,本文档不赋予您对这些专利、商标、版权或其他知识产权的任何许可。

除非另有说明,否则本文档提及的示例公司、组织、产品、域名、电子邮件地址、徽标、人物、地点和事件皆属虚构,与任何真实的公司、组织、产品、域名、电子邮件地址、徽标、个人、地点或事件无关。
 
Ó 2007 Microsoft Corporation. 保留所有权利。

Microsoft 和 SQL Server 是 Microsoft Corporation 在美国和/或其他国家/地区的注册商标或商标。

本文档中提及的真实的公司和产品名称可能是其各自所有者的商标。

导言
Microsoft 使用 FOR XML 和 OPENXML Transact-SQL 关键字在 Microsoft SQL Server 2000中引入了 XML 的相关功能,这使开发人员可以编写 Transact-SQL 代码将查询结果作为 XML 流进行检索,并将 XML 文档拆分到行集中。通过引入支持 XSD 架构验证、基于XQuery 的操作和 XML 索引的本机 xml 数据类型,SQL Server 2005显著地扩展了其 XML 的功能。SQL Server 2008 在以前版本中 XML 功能的基础上对其进行了改进,以应对客户在数据库中存储和操作 XML 数据时面临的挑战。
 

SQL Server XML 功能的演变

SQL Server 的 XML 功能随着 SQL Server 2000 及其后续每个版本的发布不断演变。在介绍 SQL Server 2008 中的增强功能之前,概述以前版本中 XML 功能的演变很有用。

SQL Server 2000 中的 XML 功能

在 SQL Server 2000 中,Microsoft 引入了 FOR XML 和 OPENXML Transact-SQL 关键字。FOR XML 是 SELECT 语句的扩展,它返回的查询结果是 XML 流,如下面的示例所示。

SELECT ProductID, ProductName
FROM Products Product
FOR XML AUTO

此次查询返回一个 XML 片段,如下面的示例所示。

<Product ProductID="1" ProductName="Widget"/>
<Product ProductID="2" ProductName="Sprocket"/>


OPENXML 功能通过从 XML 文档中创建行集的方法执行与 FOR XML 语句相反的功能,如下面的示例所示。

DECLARE @doc nvarchar(1000)
SET @doc = '<Order OrderID = "1011">
   <Item ProductID="1" Quantity="2"/>
   <Item ProductID="2" Quantity="1"/>
  </Order>
'
DECLARE @xmlDoc integer
EXEC sp_xml_preparedocument @xmlDoc OUTPUT, @doc
SELECT * FROM
OPENXML (
@xmlDoc, 'Order/Item', 1)
WITH
(OrderID
integer '../@OrderID',
ProductID
integer,
Quantity
integer)
EXEC sp_xml_removedocument @xmlDoc


注意,使用 sp_xml_preparedocument 和 sp_xml_removedocument 存储过程为 XML 文档创建节点树的内存表示。这段Transact-SQL 代码返回如下行集。
 
OrderID ProductID Quantity   
1011 1 2   
1011 2 1 

SQL Server 2005 中的 XML 功能
在Ú SQL Server 2005中,FOR XML 功能新增了根元素和元素名称的新选项,增强了嵌套ËǶÌ× FOR调用的能力,因此可以构建复杂的层次结构,新增的Ä PATH模式允许定义使用ʹÓà Xp语法进行检索的 XML 结构,如下面的示例所示

。¾SELECT ProductID AS '@ProductID',
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 数据创建变量和列,如下面的示例所示。

CREATE TABLE SalesOrders
(OrderID
integer PRIMARY KEY,
OrderDate
datetime,
CustomerID
integer,
OrderNotes xml)


可以使用 xml 数据类型存储数据库中的标记文档或半结构化数据。列和变量可以用于非类型 XML 和类型 XML,其中后者是由 XML 架构定义 (XSD) 架构验证的。开发人员可以使用 CREATE XML SCHEMA COLLECTION 语句为数据验证定义架构,如下面的示例所示。

CREATE XML SCHEMA COLLECTION ProductSchema AS
'<?xml version="1.0" encoding="UTF-16"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <!-- schema declarations go here -->
</xs:schema>


创建架构集合后,可以通过引用该架构集合并使用其包含的架构声明关联 xml 变量或列,如下面的示例所示。

CREATE TABLE SalesOrders
(OrderID
integer PRIMARY KEY,
OrderDate
datetime,
CustomerID
integer,
OrderNotes xml(ProductSchema))


在插入或更新值时,相关架构集合中的声明将验证类型 XML,出于符合或兼容性原因,有可能强制实施 XML 数据结构的业务规则。
xml 数据类型也提供了一些方法,这些方法可以用于在实例中查询和操纵 XML 数据。例如,可以在 xml 数据类型的实例中使用 query 方法查询 XML,如下面的示例所示。

declare @x 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 文档,如下面的示例所示。

<CustomerList>
  
<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 实例中节点的查询性能。

CREATE PRIMARY XML INDEX idx_xml_Notes
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:complexType name="Order" mixed="true">
  
<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 元素。

<Invoice xmlns="http://adventure-works.com/order"
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:simpleType name="sizeListType">
  
<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)的列表。

CREATE XML SCHEMA COLLECTION CatalogSizeSchema AS
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 数据类型的有效实例。

<Catalog>
  
<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 表达式中的变量赋值,如下面的示例所示:

declare @x 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(
'<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。

<Orders>
<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:

<Products>
  
<Bike>Mountain Bike</Bike>
  
<Bike>Road Bike</Bike>
</Products>


可以使用以下代码向产品列表中插入一个新自行车:

DECLARE @newBike xml
SET @newBike = '<Bike>Racing Bike</Bike>'
SET @productList.modify
(
'insert sql:variable("@newBike") as last into (/Products)[1]')


运行这段代码后,@productList 变量中会包括以下 XML。

<Products>
  
<Bike>Mountain Bike</Bike>
  
<Bike>Road Bike</Bike>
  
<Bike>Racing Bike</Bike>
</Products>


结束语
SQL Server 2008 除提供对 SQL Server 2005已有 XML 的全面支持外,还扩展了构建能够合并关系数据和 XML 的强大数据库解决方案的功能。XML 架构支持的改进和 xml 数据类型的增加,对应用程序开发人员具有极大的吸引力。

获取更多信息:
http://www.microsoft.com/sql

本文对您有帮助吗?请告诉我们您的感受。如果从1(差)到5(极好)的分值中进行选择,您认为本文应该打几分?原因是什么?例如:
您是否认为由于提供了很好的例子、精美的屏幕截图、清晰的文字描述或其他原因而应该给它高分?
您是否认为由于用例不当、屏幕截图模糊、文字描述含混不清而应该给它低分?
您的意见有助于我们改善所发布白皮书的质量。提交意见。
 

0
相关文章