WEB开发网
开发学院数据库MSSQL Server SQL Server 2008中有关XML的新功能 阅读

SQL Server 2008中有关XML的新功能

 2008-04-14 09:53:49 来源:WEB开发网   
核心提示:1 导言Microsoft 在Microsoft SQL Server 2000中推出了与XML相关的功能以及Transact-SQL 关键字FOR XML和OPENXML ,这使得开发人员可以编写Transact-SQL代码来获取XML流形式的查询结果,SQL Server 2008中有关XML的新功能,并将一个XM

1 导言

Microsoft 在Microsoft SQL Server 2000中推出了与XML相关的功能以及Transact-SQL 关键字FOR XML和OPENXML ,这使得开发人员可以编写Transact-SQL代码来获取XML流形式的查询结果,并将一个XML文档分割成一个rowset。SQL Server 2005显著的扩展了这些XML功能,推出了一个支持XSD schema验证、基于XQuery的操作和XML索引的本地的xml 数据类型。SQL Server 2008建立在之前版本的XML功能基础之上,做了改进来迎接客户在存储和操纵数据库中的XML数据时所面临的挑战。

2 SQL Server XML 功能的发展历程

SQL Server的XML功能随着从SQL Server2000版本以来的每一个版本而不断发展。在我们检查SQL Server 2008中的改进之前,通过之前的版本来总结XML功能的发展历程可能会比较有用。

2.1 SQL Server 2000中的XML功能

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

  SELECTProductID,ProductName
  FROMProductsProduct
  FORXMLAUTO

这个查询返回一个如下面示例所示的XML片断:  

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

OPENXML 功能执行与FOR XML 条件子句相反的功能,它创建一个XML文档的rowset ,如下面的示例所示:

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 代码返回下面的rowset。 

OrderIDProductIDQuantity
101112
101121

2.2 SQL Server 2005中的XML功能

在SQL Server 2005中,FOR XML 功能得到了增强,它有了对根元素和元素名称的新的选项、使用FOR XML 调用以便你可以建立复杂的层次关系的能力、和一个新的使得你可以定义将要使用XPath 语法来提取的XML结构的PATH 模式,如下面的示例所示:

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 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 数据类型来存储数据库中的文档或数据。列和变量可以用于非类型化的XML或类型化的XML,后者是对一个XML Schema 定义(XML Schema Definition ,XSD)的schema有效。如果要为数据验证进行定义,开发人员可以使用CREATE XML SCHEMA COLLECTION 语句,如下面的示例所示:

在创建了一个schema 集合后,你可以通过参照schema集合将一个xml变量或列与它所包含的schema 声明结合起来,如下面的示例所示:

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

类型化XML在插入值或更新值时对关联的schema 集合的声明进行验证,这使得可以为了遵从性检查或兼容性原因而加强关于XML数据的结构的业务规则。

xml 数据类型还提供了一些方法,使得你可以使用它们来查询和操纵实例的XML数据。例如,你可以使用query 方法来查询xml 数据类型的一个实例的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>')

这个例子中的查询使用了一个XQuery 表达式,这个表达式找出文档中的每一个Invoice 元素,并返回一个包含每一个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索引,和一个PATH类型的次要XML索引,它可以提高使用XPath表达式来标识一个XML实例中的节点的查询的性能。

  CREATEPRIMARYXMLINDEXidx_xml_Notes
  ONSalesOrders(Notes)
  GO
  CREATEXMLINDEXidx_xml_Path_Notes
  ONSalesOrders(Notes)
  USINGXMLINDEXidx_xml_Notes
  FORPATH
  GO

2.3 SQL Server 2008中的XML功能

XML功能是在SQL Server 2000和SQL Server 2005中推出的,在SQL Server 2008中得到了增强。在SQL Server 2008中主要的与XML相关的改进包括:

· 改进了schema 验证能力

· 增强了对XQuery 的支持

· 增强了XML数据操纵语言(DML)的插入功能

本篇白皮书的其余部分描述了这些增强之处,并介绍了你怎样在SQL Server 2008中使用它们来实现更好的XML解决方案。

3 增强了XML Schema验证功能

你可以使用一个或多个XSD schema执行遵从性检查,以此来验证XML数据。一个schema为某个特定的XML数据结构定义被允许的XML元素和属性,并通常用于确保XML文档按正确的结构包含进了所要求的所有数据元素。

SQL Server 2005推出了通过使用XML schema 集合来进行XML数据验证。一般的方法是使用CREATE XML SCHEMA COLLECTION语句创建包含了针对你的XML数据的schema 规则的schema集合,然后当你要定义一个必须符合这个schema 集合中的schema 规则的xml字段或变量时参照这个schema集合名称。然后SQL Server会按照这个schema集合中的schema规则来验证插入或更新进这个字段或变量的所有数据。

在SQL Server 2005中的XML Schema支持实现了一个广泛的纯XML Schema规格的子集,并涵盖了最常见的XML验证场景。SQL Server 2008扩展了这个支持,使得它包含下面新增加的由客户确定的schema 验证要求:

· 对lax 验证的支持

· 对dateTime、time和date 验证的完全支持,包括时区信息的保存。

· 改进了对union和list类型的支持

3.1 支持Lax验证

XML Schema通过使用any、anyAttribute和anyType声明来支持XML文档中的通配符。例如,看看下面的XML schema 声明:

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

这个schema 声明定义了一个叫做Order 的XML元素,它必须包含叫做CustomerName和OrderTotal的子元素。此外,这个元素可以包含Order类型所属的命名空间之外的其它命名空间的无限制数目的其它元素。下面的XML显示了一个包含由这个schema 声明所定义的Order 元素的一个实例的XML文档。注意这个order 还包含了一个shp:Delivery 元素,它没有在schema中明确定义。

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

对通配符的验证取决于在schema定义中的通配符的processContents 属性。在SQL Server 2005中,schema可以使用用于any和anyAttribute声明的skip和strict 的processContents值。在前面的示例中,这个通配符元素的processContents属性被设置为skip,所以不会对这个元素的内容进行验证。即使这个schema集合包含一个对shp:Delivery元素的声明(例如,定义一组有效的发送方法对Order元素中的通配符),这个元素也不会被验证,除非在Order元素中对通配符的声明将它的processContents属性设置为strict。

SQL Server 2008增加了对第三方验证的支持。通过将一个通配符的processContents属性设置为lax ,你可以对具有相应的schema 声明的任何元素进行验证,但忽略没有在schema 中定义的所有元素。继续前面的示例,如果你将schema中对通配符元素的声明中的processContents属性设置为lax 并增加一个对shp:Delivery元素的声明,那么在XML文档中的shp:Delivery 元素会被进行验证。然而,如果不是shp:Delivery 元素,而是该文档包含了一个没有在schema中声明的元素,那么这个元素会被忽略掉。

此外,XML Schema 规格定义anyType声明具有对它的内容模型的lax处理方式。SQL Server 2005不支持lax处理,所以会严格的对内容进行验证。SQL Server 2008支持anyType 内容的lax处理,因此内容会被正确的进行验证。

3.2 对 xs:dateTime 的完全支持

你可以在一个XML schema 中使用dateTime数据类型来定义日期和时间数据。日期和时间数据以2007-08-01T09:30:00:000Z的格式来显示,这表示的是通用协调时(UTC)2007年8月1日早上9:30,这用Z表示。其它的时区显示的时间与通用协调时间不同,因此例如你能使用太平洋标准时间2007-12-25T06:00:00:000-8:00来显示2007年12月25日的早上6:00(它比UTC时间滞后8小时)。

XML Schema 规格定义了可选择的dateTime、date和time 数据类型的时区组件。然而,在SQL Server 2005中你必须提供一个用于dateTime、date和time数据的时区。此外,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数据时你可以省略时区信息,并且你提供的任何时区信息都会被保存下来。

3.3 Union和List类型

你可以使用XML schema 将你的XML数据的数据类型定义为允许将一个有限集合的值赋给具有多个值的元素和属性。例如,你可能定义一个sizeListType类型,它使产品定义中的一个AvaliableSizes元素的赋值限制为S、M和L。SQL Server 2005支持XML schema包含这些简单的类型定义和限制。例如,你可以使用一个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>

这个schema 声明使你可以创建一个列出所有型号的元素,其中产品可以按照被空格分开的一组值来购买,如下面的示例所示:  

<AvailableSizes>S M L</AvailableSizes>

然而,如果你想支持两种不同的方式来表达一个产品的型号呢?例如,假设一个自行车产品零售商卖具有大、中、小型号的骑自行车穿的衣服,但是还想按照衣服尺寸来卖(例如18、20、22和24)?为了使你能够这样做,SQL Server 2008增加了对包含list类型的union类型的支持,你可以使用它将多个类型定义和限制合并到一个单独的类型中去。例如,下面的Transact-SQL代码创建了一个XML schema集合,它定义了一个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>'

有了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 类型的schema 声明。

4 增强了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不允许对构造元素赋值。

5 XML DML增强

像可以使用XQuery 表达式对XML数据执行操作一样,xml 数据类型支持XML DML 表达式通过它的modify 方法来执行insert、replace value of和delete。你可以使用这些XML DML 表达式来操纵一个xml 列或变量中的XML数据。

SQL Server 2008增加了对在一个要执行插入XML数据到一个现有的XML结构中去的insert表达式中使用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>

6 总结

SQL Server 2008建立在SQL Server 2005中对XML的全面支持之上,并扩展了建立强大的将关系数据和XML结合在一起的数据库解决方案的能力。应用程序开发人员将会发现对XML schema 支持的改进和对xml 数据类型的增强所带来的好处是非常吸引人的。

Tags:SQL Server 有关

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接