孤独的猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

CREATETABLE SalesOrders
(OrderID
integerPRIMARYKEY,
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 变量或列,如下面的示例所示。

CREATETABLE SalesOrders
(OrderID
integerPRIMARYKEY,
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 实例中节点的查询性能。

CREATEPRIMARY 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>2224</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>
posted on 2012-12-03 16:00  孤独的猫  阅读(3140)  评论(0编辑  收藏  举报