Microsoft2005中的支持

来源:互联网 发布:淘宝男装金冠店铺 编辑:程序博客网 时间:2024/05/21 04:24
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

ShankarPal、MarkFussell和IrwinDolobowsky

MicrosoftCorporation

适用于:MicrosoftSQLServer

简介

可扩展标记语言(XML)作为一种与平台无关的数据表示形式已被广泛采用。它对于在松散耦合且完全不同的系统,以及各种企业到企业(B2B)应用和工作流范畴内交换信息是很有用的。数据交换已成为XML技术的主要驱动力之一。.

XML在企业应用程序中的使用正日益广泛,它主要用于对半结构化和非结构化数据进行建模。文档管理就是这样的一种应用程序。像电子邮件这样的文档是半结构化性质的。如果文档以XML的形式存储在服务器中,就可以开发功能强大的应用程序来根据文档内容检索文档、查询部分内容(例如查找标题包含单词“背景”的部分),以及查询文档聚合。如果存在能够生成和使用XML的应用程序,则这样的方案就变得可行了。例如,MicrosoftOffice2003系统允许用户以XML标记的形式生成、、Visio和Infopath文档。

为什么使用关系数据库来存储XML数据?

将XML数据存储在关系数据库中会给数据管理和查询处理带来好处。SQLServer提供了强大的查询和修改关系数据的能力,而且已经扩展到查询和修改XML数据。这使得可以利用在过去的版本上所进行的投资,就如同基于成本的优化和数据存储领域一样。例如,关系数据库中的索引技术已经广为人知,而且已经扩展到用于索引XML数据,这样就可以使用基于成本的决策来优化查询。

XML数据可以与现有的关系数据和SQL应用程序进行互操作,这样就可以在需要进行数据建模而又不破坏现有的应用程序的系统中引入XML。数据库服务器还提供了管理功能来管理XML数据(例如备份、恢复和复制)。

这些功能促进了对SQLServer2005中的原生XML支持的需求,从而解决了不断增加的XML使用的问题。SQLServer2005中的XML支持将给企业应用程序开发带来好处。

下面几部分将概述SQLServer2000和2005中的XML支持,描述一些推动XML使用的方案,并且详细讨论服务器端和客户端的XML功能集。

SQLServer2000中的XML支持

这一部分简要概述了SQLServer2000中的XML支持,以及随后发布的SQLXML客户端平台Web版,它提供了丰富的支持来将关系数据映射到XML数据或将XML数据映射到关系数据。

服务器端支持

在服务器上,XML数据可以从表生成,并通过在SELECT语句中使用FORXML子句来查询结果。这对于数据交换和Web服务应用程序是很理想的。FORXML的逆函数是一个名为OpenXML的关系行集合生成器函数;它通过求XPath1.0表达式的值来从XML数据提取值,并将其放到行集合的列中。应用程序使用OpenXML来“切碎”传入XML数据,并将其存放到表中,或者用于通过T-SQL语言进行的查询。

客户端支持

SQLServer2000对客户端编程的支持称为SQLXML。这项技术的核心是XML视图,它是XML架构和关系表之间的双向映射。SQLServer2000只支持XDR架构的映射,尽管在后续的Web版中增加了对XSD的支持。XML视图允许使用XPath1.0的一个子集来进行查询,其中,可以使用映射将路径表达式转换成底层表中的SQL查询,并且将查询结果打包成XML结果。

SQLXML还支持您创建XML模板,这使得您可以创建带有动态部分的XML文档。在XML文档中,您可以嵌入FORXML查询和/或映射查询之上的XPath1.0表达式。在执行XML模板时,可以用查询的结果来替换查询块。通过这种方式,您可以创建带有某些静态内容和某些数据驱动的动态内容的XML文档。

在SQLServer2000中,有两种访问SQLXML功能的主要方法:

SQLXMLOLEDBProvider。SQLXMLOLEDBProvider是一个OLEDB提供程序,它通过ADO公开MicrosoftSQLXML功能。

HTTP访问。SQLServer2000中的SQLXML功能也可以使用SQLXMLISAPI过滤器通过HTTP进行访问。通过使用我们的配置工具,您可以建立来检索传入请求,从而通过HTTP执行XML模板、XML视图之上的FORXML和XPath1.0语句。

XML支持的局限性

服务器和客户端编程平台为基于表格和XML数据之间的映射生成和使用XML数据提供了丰富的支持。这能够相当好地处理结构化XML数据。在SQLXML中,查询语言是XPath1.0的一个子集,并且有一些局限性。例如,不支持descendant-or-self轴(//)。因此,在开发某些解决方案时会存在一定的限制。例如,不保存XML文档顺序,而这对于像文档管理这样的应用程序来说是非常关键的。此外,还不支持递归的XML架构。尽管存在这样一些局限性,但是客户端SQLXML和服务器XML功能还是在应用程序开发中得到了广泛的使用。SQLServer2005解决了许多这样的限制,扩展了关系XML交换功能,并且还提供了原生XML支持

SQLServer2005中的XML支持概述

这一部分简要概述了SQLServer2005中增加的新的XML支持,它是通过框架V2.0中的支持和本机客户端数据访问(如OLEDB)进行补充的。

XML数据类型

XML数据模型具有一些特性,这些特性使得映射到关系数据模型非常困难,如果不是完全不可能的话。XML数据具有可以递归的层次结构;关系数据库提供对层次数据(建模为外键关系)的弱支持。文档顺序是XML实例的固有属性,并且必须保存在查询结果中。这与关系数据形成了对比,关系数据是无序的,必须通过附加的排序列来强制进行排序。在查询时重新组合结果是很费力的,因为实际的XML架构将XML数据分解到大量的表中。

SQLServer2005引入了一种称为XML的本机数据类型。用户可以创建这样的表,它在关系列之外还有一个或多个XML类型的列;此外,还允许带有变量和参数。为了更好地支持XML模型特征(例如文档顺序和递归结构),XML值以内部格式存储为大型二进制对象(BLOB)。

SQLServer2005提供了XML架构集合,可以将其作为一种方法来以元数据的形式管理W3CXML架构。XML数据类型可以与XML架构集合相关联,以便对XML实例强加架构限制。当XML数据与XML架构集合相关联时,它称为类型化的XML;否则,就称为非类型化的XML。在一个框架中可以同时容纳类型化的XML和非类型化的XML,保留XML数据模型,并且强制采用XML语义进行查询处理。底层关系基础结构被广泛用于这一目的。它支持关系数据和XML数据之间的互操作,这为更广泛地采用XML功能开辟了道路。

XML数据类型查询和数据修改

可以使用T-SQLSELECT语句来检索XML实例。在XML数据类型中提供了五种内置的方法来查询和修改XML实例。

XML数据类型的方法接受XQuery,它是一种新出现的W3C标准语言(目前处于LastCall(最后请求)状态),并且包括导航语言XPath2.0。也可以使用一种语言来修改XML数据,比如添加或删除子树和更新标量值。与一大组函数一起,嵌入式的XQuery和数据修改语言为处理XML数据提供了丰富的支持

XQuery类型系统与W3CXML架构类型是一致的。大多数SQL类型与XQuery类型系统是兼容的(例如,小数)。少数类型(例如,xs:duration)是以内部格式存储的,并且可以通过适当的解释来与XQuery类型系统兼容。

编译阶段检查XQuery表达式和数据修改语句的静态类型的正确性,并且在类型化XML的情况下使用XML架构来进行类型推理。如果表达式由于类型冲突而在运行时失败,则会产生静态类型错误。

XML索引

查询执行在运行时处理每个XML实例;如果XML值比较大或需要在表的许多行中对查询进行求值,则查询执行就会变得非常费时。因此提供了一种索引XML列的机制来加速查询。

B+树广泛用于建立关系数据的索引。XML列的主XML索引在该列中XML实例的所有标记、值和路径上都创建一个B+树索引。通过这种方式,可以有效地对XML数据中的查询进行求值,并且在保留文档顺序和文档结构的同时从B+树重新组合XML结果。

可以在XML列中创建次XML索引来加速不同类别的常见查询:PATH索引(用于基于路径的查询)、PROPERTY索引(用于属性包的情况)和VALUE索引(用于基于值的查询)。

XML架构处理

XML列、变量和参数可以根据XML架构的集合(它可能与另一个集合相关(例如,通过使用)或不相关)有选择地进行类型化。每个类型化的XML实例都从它遵循的XML架构集合指定目标命名空间。数据库引擎在数据分配和修改时根据XML架构来验证实例的有效性。

XML架构信息用于存储和查询优化。类型化的XML实例在内部的二进制表示中包含类型化的值,这与XML索引中的一样。通过这种方式,可以有效地处理类型化XML数据。

关系数据和XML数据的集成

用户可以在同一个数据库中存储关系数据和XML数据。简而言之,数据库引擎除了知道如何遵循关系数据模型之外,还知道如何遵循XML数据模型。在升级到SQLServer2005之后,关系数据和SQL应用程序仍然能够正常工作。在服务器上,可以将驻留在文件和文本或图像列中的XML数据移到XML数据类型的列中。通过使用XML数据类型的方法,可以建立XML列的索引,并对其进行查询和修改。

数据库利用现有的关系基础结构和引擎组件(例如存储引擎和查询处理器)来进行XML处理。例如,XML索引可以创建B+树,而且可以在Showplan输出中查看查询计划。通过集成到关系框架中,数据管理功能(如备份/恢复和复制)可用于XML数据。同样地,新的数据管理功能(如数据库镜像和快照隔离)可以处理XML数据类型,以提供无缝的用户体验。

结构化数据应该存储在表和关系列中。当应用程序需要执行细粒度查询和数据修改时,对于使用XML的半结构化数据和标记数据,XML数据类型是比较合适的选择。

FORXML和OpenXML增强

现有的FORXML功能已经在几个方面得到了增强。它能够处理XML数据类型的实例和其他新的SQL类型,例如[n]varchar(max)。

新的TYPE指令生成的XML数据类型实例可以分配给XML列、变量或参数,也可以使用XML数据类型的方法进行查询。这允许嵌套SELECT...FORXMLTYPE语句。

PATH模式允许用户指定出现列值的XML树中的路径,并且与上述嵌套一起使用时比FORXMLEXPLICIT更易于编写。

XSINIL指令与ELEMENTS一起使用,可以将NULL映射到带有属性xsi:nil="true"的元素。另外,新的ROOT指令还允许在所有的FORXML模式下指定根节点。新的XMLSCHEMA指令生成XSD内联架构。

OpenXML的功能增强包括在sp_preparedocument中接受XML数据类型以及在行集中生成XML和新的SQL类型的列。

对XML数据类型的客户端访问

客户端可以通过几种方式访问服务器中的XML数据。使用ODBC和OLEDB的本机SQL客户端访问以Unicode字符串的形式传递XML数据类型。OLEDB还提供对流Unicode数据的XML数据类型的ISequentialStream访问。

托管访问通过.NET框架V2.0中的将XML数据作为一个名为SqlXml的新类进行传递。它支持一个名为CreateReader()的方法,该方法返回XmlReader实例来读取返回的XML。同样地,数据集能够将XML数据类型的实例加载到中间层的列,中间层可以作为XML文档进行编辑,并且重新保存到SQLServer。这两者都支持对服务器发出SQL查询,以检索在中间层操作的XML列。

在SQLServer2005中,可以使用直接对HTTP终结点进行的访问来查询、检索和修改XML数据。

本机和托管客户端技术都提供了新的接口来检索类型化XML列的XML架构集合。

带有XQuery的客户端XML支持

除了使用ADO.NET来检索表并将结果存放到关系数据集中之外,您还可以使用XQueryCommand类将关系数据直接加载到中间层的XML文档。该类提供了一个中间层XQuery处理器,它能够将T-SQL语句作为XQuery语言的一部分嵌入。通过这种方式,您可以查询本地XML文件,也可以从SQLServer检索数据(直接从表或者通过数据库存储程序),再将数据构造成XML格式,然后将其加载到中间层XML文档。这大大简化了SQLServer中的查询,将查询结果构造成特定的XML格式,并使其流向业务合作伙伴,而不需要将数据加载到数据集来执行数据转换。

返回页首

推动XML存储方案

XML数据变得越来越普遍.它可以表示客户数据,带有或不带有描述数据的XML架构均可。XML数据和XML架构需要在一起进行管理。实际应用程序的XML架构通常比较复杂,因而将这样的XML架构映射到表和列是一项复杂的任务。当XML架构改变或新的架构加入系统时,长时间维护这样的映射是一件很麻烦的事情。通常,XML数据存储在文件系统或数据库服务器的文本列中。文本列有数据管理方面的好处(例如,复制和备份/恢复),但是不提供任何基于数据的XML结构的查询支持。在具有原生XML支持的情况下,使用XML进行应用程序开发变得更快。

自定义属性管理

一些应用程序(例如用户界面)允许用户从一组固定的属性中进行选择。而其他应用程序则允许用户定义他们自己感兴趣的属性。如果这样的自定义属性是以XML的格式存储的,它们就可以很好地进行管理。应用程序可以支持标量属性以外的属性:

可以支持对象中的多值属性,例如,多个电话号码。

可以支持复杂属性,例如,一个文档的作者属性可能是该作者的联系信息。

可以将对象属性存储在XML数据类型的列中并建立索引,从而提高查询处理的效率。

数据交换和工作流

XML允许采用平台无关的方式在应用程序之间交换数据。可以使用XML标记将这样的数据建模为消息。代替不断地分割和生成XML消息,以XML的格式存储消息是明智的。这正是数据流所需要的。到达工作流阶段的XML消息携带着当前的状态。每个消息都需要进行处理,处理的进展记录在XML内容中(如状态改变),然后将XML数据转发到工作流处理的下一个阶段。消息可能是不同类型的,甚至可能是半结构化的,并且有不同的XML架构与它们相关联,因此将它们映射到表并不总是一件轻而易举的事。

针对不同垂直领域(如金融数据和地理空间数据)的基于XML的标准正在形成。这些标准根据可以查询和更新的实例数据来描述数据的结构。通常,实际数据采用的是二进制形式,而XML数据提供关于它们的元数据信息。

举一个简单的例子,为了将一个输入参数表传送到存储程序或函数,应用程序首先将数据转换成XML,然后将其作为一个XML数据类型参数进行传递。在存储过程或函数内,从XML参数重新生成行集。

文档管理

假设有一个呼叫中心,它采用XML文档来维护患者记录和谈话。当患者发起呼叫时,呼叫中心希望恢复前面的谈话以设置传入呼叫的情景。这可以通过查询XML标记实现,从而给应用程序带来好处。此外,还可以方便地检索以前谈话的细节并记录当前的谈话。

像电子邮件之类的文档本质上是半结构化的。带有XML标记的文档正变得越来越容易创建,例如,使用Office2003。可以将这些XML文档存储在XML列中,并建立索引,进行查询和更新。因此,通过利用原生XML支持,开发人员可以做更多的事情。

返回页首

SQLServer2005中的服务器端XML处理

SQLServer2005支持包括提供一个数据库,在这个数据库中,您可以存储关系数据和XML数据。

XML数据类型

您可以使用普通的CREATETABLE语句来创建带有XML列的表。然后就可以采用一种特别的方式来建立XML的索引。

非类型化的XML

SQLServer2005XML数据类型实现了ISOSQL-2003标准XML数据类型。因此,它不仅可以存储格式良好的XML1.0文档,而且可以存储所谓的XML内容片段(带有文本节点和任意数目的顶层元素)。在对数据进行格式良好性检查时,并不要求将XML数据类型绑定到XML架构,但是格式不规范的数据将被拒绝。

当架构不是已知先验的并且因此而导致基于映射的解决方案不可能实现时,就可以使用非类型化的XML。如果架构是已知的,但映射到关系数据模型非常复杂并且难于维护,或者存在多个架构而且这些架构是后来根据外部要求绑定到数据的,也可以使用非类型化的XML。

例:表中非类型化的XML列

下面的语句创建一个名为“docs”的表,该表带有整型主键“pk”和非类型化的XML列“xCol”:

CREATETABLEdocs(pkINTPRIMARYKEY,xColXMLnotnull)

也可以创建一个包含多个XML列或关系列、带主键或不带主键的表。

类型化的XML

如果XML架构集合中有描述XML数据的XML架构,就可以将XML架构集合与产生类型化XML的XML列相关联。可以使用XML架构来验证数据的有效性,在编译查询和数据修改语句时执行比非类型化的XML更精确的类型检查,以及优化存储和查询处理。

类型化的XML列、参数和变量可以存储XML文档或内容,可以在声明时将其指定为一个选项(分别为DOCUMENT或CONTENT,默认为CONTENT)。此外,还必须提供XML架构集合。如果每个XML实例都正好有一个顶层元素,则指定DOCUMENT;否则,使用CONTENT。查询编译器在类型检查中使用DOCUMENT标记来推理singleton顶层元素。

例:表中的类型化XML列

XML列、变量和参数可以绑定到一个XML架构集合(请参阅本文后面的“XML架构处理”一节以获得更多的详细信息和示例)。假定myCollection代表这样一个集合。下面的语句创建一个表XmlCatalog,带有使用myCollection进行类型化的XML列文档。类型化的XML列还被指定为接受XML片段,而不只是XML文档。

CREATETABLEXmlCatalog(IDINTPRIMARYKEY,DocumentXML(CONTENTmyCollection))

约束XML数据类型的列

除了类型化一个XML列之外,还可以在类型化和非类型化的XML数据类型的列中使用关系(列或行)约束。大部分SQL约束同样可应用于XML列,值得注意的唯一例外是主键和外键约束,因为XML数据类型的实例是不兼容的。因此,可以指定XML列可为空或不可为空,提供默认值,并且在列中定义CHECK约束。例如,非类型化的XML列可以有CHECK约束来验证存储的XML实例是否符合XML架构。

在下列条件下使用约束:

业务规则不能用XML架构表示。例如,花店的交付地址必须在其业务场所50英里的范围内,这可以编写成XML列中的一个约束条件。该约束条件可以包括XML数据类型的方法。

约束条件涉及表中其他的XML或非XML列。这样的一个例子就是,使XML实例中存在的Customer(/Customer/@CustId)的id与整型CustomerID列中的值相匹配。

例:约束XML列

要确定<book>的<author>的<last-name>不同于<author>的<first-name>,可以指定下列CHECK约束:

CREATETABLEdocs(pkINTPRIMARYKEY,xColXMLnotnullCONSTRAINTCK_nameCHECK(xCol.exist('/book/author[first-name=last-name]')=0))

文本编码

SQLServer2005将XML数据存储为Unicode(UTF-16)。从服务器检索的XML数据,其结果也是UTF-16编码的。如果想要采用一种不同的编码方式,就需要在检索数据之后进行必要的转换,转换的方法有两种,一种是通过强制类型转换,另一种是在中间层执行转换。例如,可以在服务器上将XML数据强制转换成varchar类型,在这种情况下,数据库引擎会通过varchar类型的排序所确定的编码方式来序列化XML。

存储XML数据

可以通过多种方式为XML列、参数或变量提供XML值。

作为隐式转换到XML数据类型的字符或二进制SQL类型。

作为文件的内容。

作为XML发布机制FORXML的输出(带有生成XML数据类型实例的TYPE指令)

对提供的值进行格式良好性检查,并且允许存储XML文档和XML片段。如果数据没有通过格式良好性检查,则拒绝它,并发出一个适当的错误消息。

对于类型化的XML,需要检查提供的值是否符合已注册到类型化XML列的XML架构集合的XML架构。如果该XML实例没有通过这种有效性验证,则拒绝它。此外,仅当CONTENT允许提供XML文档和内容时,类型化的XML中的DOCUMENT标记才将所接受的值限制为XML文档。

例:将数据插入非类型化的XML列

下列语句在表docs中新插入一行,其中在整型的pk列插入的值为1,而在XML列插入的是实例。数据(作为字符串提供)被隐式地转换为XML数据类型,并且在插入的过程中进行格式良好性检查。

INSERTINTOdocsVALUES(1,'<bookgenre="security"publicationdate="2002"ISBN="0-7356-1588-2"><title>WritingSecureCode</title><author><first-name>Michael</first-name><last-name>Howard</last-name></author><author><first-name>David</first-name><last-name>LeBlanc</last-name></author><price>39.99</price></book>')

例:将来自文件的数据插入非类型化的XML列

如下所示的INSERT语句使用OPENROWSET读取文件C:/temp/xmlfile.xml的内容作为BLOB。在表docs中新插入一行,值10作为主键,而BLOB作为XML列xCol。格式良好性检查出现在文件内容分配到XML列时。

INSERTINTOdocsSELECT10,xColFROM(SELECT*FROMOPENROWSET(BULK'C:/temp/xmlfile.xml',SINGLE_BLOB)ASxCol)ASR(xCol)

例:将数据插入类型化的XML列

类型化的XML列需要XML实例数据指定用于对其进行类型化的XML架构的目标命名空间(该命名空间可以为空)。在下面的示例中,这是通过命名空间声明xmlns=http://myDVD来实现的。

INSERTXmlCatalogVALUES(2,'<?xmlversion="1.0"?><dvdstorexmlns="http://myDVD"><dvdgenre="Comedy"releasedate="2003"><title>MyBigFatGreekWedding</title><price>19.99</price></dvd></dvdstore>')

例:存储使用带有TYPE指令的FORXML生成的XML数据

通过TYPE指令增强的FORXML可以生成像XML数据类型实例这样的结果。结果XML可以分配到XML列、变量或参数。在下面的语句中,使用FORXMLTYPE生成的XML实例被分配给XML数据类型的变量@xVar。可以使用XML数据类型的方法来查询变量。

DECLARE@xVarXMLSET@xVar=(SELECT*FROMdocsFORXMLAUTO,TYPE)

存储表示

XML数据类型的实例存储在内部的二进制表示中,该表示是可流化的,并且经过了优化,从而可以更有效地进行解析。标记映射到整型值,而映射的值存储在内部表示中。这也产生了一些数据的压缩。

对于非类型化的XML,节点值存储为Unicode(UTF-16)字符串,因此需要进行运行时类型转换才能执行操作。例如,为了求谓词/book/price>9.99的值,必须将该书的价格值转换为小数。而对于类型化的XML,值的编码类型为在XML架构中指定的类型。这使得数据的解析更加有效,并且还不必进行运行时转换。

存储的二进制形式被限制为每XML实例2GB,这可以适应大部分的XML数据。此外,XML层次的深度还被限制为128层。

XML数据的信息集内容被保留。但是,它不可能是与文本XML一模一样的副本,因为下列信息没有保留:无关紧要的空白、属性的顺序、命名空间前缀和XML声明。

数据建模考虑事项

通常,关系数据类型和XML数据类型的列的组合比较适合数据建模。可以将XML数据中的一些值存储在关系列中,而将其余的值或全部的XML值存储在XML列中。这可以产生更好的性能和锁定特性。

对于singleton值(即单值属性),XML数据中的值可以提升为同一个表中的计算列。多值属性需要单独的属性表,该表必须使用触发器进行填充和维护。查询需要直接针对属性表进行编写。

对于锁定和更新特性,存储在XML列中的XML数据的粒度是至关重要的。SQLServer将相同的锁定机制用于XML和非XML数据。如果粒度比较大,则在多用户的情况下,为了更新而锁定大的XML实例会引起吞吐量的下降。而另一方面,严格的分解会失去对象的封装性并增加重新组合的成本。

查询和修改XML数据

查询存储在XML列中的XML实例需要解析列中的二进制XML数据。与解析文本形式的XML数据相比,解析二进制的XML要快得多。XML索引避免了重新解析,这将在“建立XML数据的索引”一节中进行讨论。

XML数据类型中的方法

如果感兴趣,可以检索全部XML值,也可以检索部分XML实例。这可以使用四个XML数据类型的方法来实现:query()value()exist()nodes(),它们接受XQuery表达式作为参数。第五个方法modify()允许修改XML数据并接受XML数据修改语句作为输入。

query()方法用于提取XML实例的部分。XQuery表达式求值为一个XML节点列表。以这些节点中的每一个为根的子树按照文档顺序返回。结果类型为非类型化的XML。

value()方法从XML实例提取标量值。它返回XQuery表达式所求值的节点的值。该值被转换为value()方法的第二个参数所指定的T-SQL类型。

exist()方法用于对XML实例进行存在性检查。如果XQuery表达式求值为非空节点列表,则返回1;否则,返回0。

nodes()方法产生特定XML数据类型的实例,每个实例都将其上下文设置为XQuery表达式所求值的不同节点。特定的XML数据类型支持query()value()nodes()exist()方法,并且可以用于count(*)聚合和NULL检查。所有其他的使用都会产生错误。

modify()方法允许修改XML实例的某些部分,例如添加或删除子树,或者更新标量值(如将书的价格从9.99替换为39.99)。

例:使用query()方法

考虑下面的表docs的XML列xCol中的查询,它提取元素下的任何位置的id为123的元素。该查询也从整型主键列检索值。SELECT列表中的query()方法会为生成元素序列的表中的每一行进行求值,元素及其子树是按照文档顺序进行检索的。对于每个XML实例,如果没有id为123的元素或者其下没有元素,则不会返回结果,也就是说,query()方法的返回值为NULL。

SELECTpk,xCol.query('/doc[@id=123]//section')FROMdocs

NULL返回值可以在外部SELECT语句中过滤掉。或者也可以使用exist()方法,如下一个示例所示。

例:使用exist()方法

考虑下面的查询,它在表docs的XML列xCol中包括query()exist()方法。exist()方法求路径表达式/doc[@id=123]的值,检查是否存在顶层元素,该元素具有一个称为id的属性,且其值为123。对于每个这样的行,SELECT子句中的query()方法都会进行求值;在这个示例中,query()方法在元素下的任何位置都产生一个元素序列。从exist()方法返回0的任何行都会被忽略。

SELECTxCol.query('/doc[@id=123]//section')FROMdocsWHERExCol.exist('/doc[@id=123]')=1

例:使用value()方法

下面的查询使用value()方法以Unicode字符串的形式提取文档第三部分的标题。结果的SQL类型的nvarchar(max)被指定为value()方法的第二个参数。XQuery函数data()从节点提取标量值。

SELECTxCol.value('data((/doc//section[@num=3]/heading)[1])','nvarchar(max)')FROMdocs

XQuery语言

众多的XML都来源于存储在文件系统、Web服务或配置文件中的Office文档。事实上,以XML格式或作为虚拟XML文档生成的数据正在不断地增加。为了处理这些数量越来越多的数据,一种强大的查询语言XQuery应运而生。在XQuery语言规范(位于http://www.w3.org/TR/xquery)中将选择XQuery的理由描述为:

一种巧妙地使用XML结构的查询语言,可以跨各种数据表示查询,而不管这些数据是物理存储在XML中,还是通过中间件被视为XML。该规范描述了一种称为XQuery的查询语言,它旨在能广泛应用于许多类型的XML数据源。

XQuery旨在满足W3CXML查询工作组XML查询1.0要求和XML查询用例中的用例所确定的要求。它是一种旨在使查询简洁易懂的语言。它还相当地灵活,可以查询大范围的XML信息源,其中包括数据库和文档。

XQuery还可以概括为如下表述:XQuery语言之于XML正如SQL语言之于关系数据库。

内嵌于T-SQL的Xquery子集(位于http://www.w3.org/TR/xquery/)是一种支持查询XML数据类型的语言。这种语言正在由WorldwideWebConsortium(W3C)进行开发(目前处于最后请求状态),所有主要的数据库厂商(包括Microsoft在内)都参与其中。我们的实现与2003年11月发布的XQuery草案是一致的。

XQuery将XPath2.0作为导航语言包括在内。SQLServer2005的XQuery实现提供了用于遍历节点(for)、节点检查(where)、返回值(return)和排序(orderby)的构造。它也提供了用于在查询过程中重新进行数据构形的元素构造。

SQLServer2005还提供了用于XML数据类型的数据修改(DML)的语言构造(请参阅下面的“数据修改”一节以获得更多信息)。下面的示例演示了如何将XQuery用于XML数据类型。

例:使用XQuery中丰富的语言构造

下面的查询显示了如何一起使用几个XQuery语言构造。它从id为123的文档返回区域号为3和更高的区域中的标题,并将其包装在新标记中。

SELECTpk,xCol.query('for$sin/doc[@id=123]//sectionwhere$s/@num>=3return<topic>{data($s/heading)}</topic>')FROMdocs

“for”遍历id为123的<doc>元素下的所有<section>元素,并且将每个这样的<section>元素绑定到变量$s。“where”确保区域号(<section>元素的@num属性)为3或更高。该查询按照文档顺序返回区域<heading>中的值,并且将其包装在一个称为<topic>的构造元素中。

查询编译和执行

SQL语句是由SQL解析器解析的。当它遇到XQuery表达式时,它就会跳转到XQuery编译器,然后编译XQuery表达式。这会产生一个查询树,并将其嫁接到整个查询的查询树上。

整个查询树会进行查询优化并产生物理查询计划,该计划是根据基于成本的评估得出的。Showplan输出显示了大部分关系运算符和一些新的运算符(例如,用于XML处理的UDX)。

查询执行与关系框架中的其余部分一样,都是面向元组的。在表docs的每一行上都求WHERE子句的值;这需要在运行时解析XMLBLOB以求出XML数据类型方法的值。如果条件满足,则锁定行,然后在行中求SELECT子句的值。结果以XML数据类型的形式产生(用于query()方法),并且转换成指定的目标类型(用于value()方法)。

而如果该行不满足WHERE子句中的条件,它就会被忽略,执行转到下一行。

XML数据修改

SQLServer2005提供了用于数据修改的构造作为对XQuery的一个扩展。子树可以在指定的节点之前或之后插入,或者作为最左边或最右边的子节点插入。此外,子树也可以插入到父节点,在这种情况下,它成为父节点最右边的子节点。属性、元素和文本节点插入都支持

支持删除子树。在这种情况下,整个子树就从XML实例中被移除。

标量值可以用新的标量值进行替换。

例:将子树插入XML实例

这个示例显示了modify()方法的使用,它将一个新的<section>元素插入编号为1的元素的右边。

UPDATEdocsSETxCol.modify('insert<sectionnum="2"><heading>Background</heading></section>after(/doc/section[@num=1])[1]')

例:将这本书的价格更新为$49.99

下面的更新语句将ISBN为1-8610-0311-0的书的<price>替换为$49.99。该XML实例是通过XML架构http://myBooksinstance进行类型化的,因而就有了XML数据修改语句中的命名空间声明。

UPDATEXmlCatalogSETDocument.modify('defaultnamespace="http://myBooks"replacevalueof(/bookstore/book[@ISBN="1-8610-0311-0"]/price)[1]with49.99')

类型检查和静态错误

XQuery引入了类型检查。编译阶段检查XQuery表达式和数据修改语句的静态类型正确性,并且将XML架构用于类型推理(在类型化XML的情况下)。如果表达式在运行时由于类型安全冲突而失败,则会产生静态类型错误。静态错误的例子有:将一个字符串与一个整数相加、在操作需要单值的地方接收一个值序列,以及查询不存在的节点来查找类型化数据。对于因类型不匹配而导致的静态错误,显式转换到正确的类型是一种变通方法。XQuery运行时错误被转换成空序列。

如果编译器不能确定在运行时是否保证有singleton元素,则需要singleton元素的定位步骤、函数参数和运算符(例如,eq)就会返回错误。这种问题常常因非类型化的数据而产生。例如,查找属性需要singleton父元素;顺序选择单个的父节点就足够了。

例:value()方法中的类型检查

下面的查询是在非类型化的XML列中进行的,它需要//author/last-name中的顺序规范,因为value()方法需要singleton节点作为第一个参数。如果没有,则编译器就不能确定在运行时是否只出现一个<last-name>节点。

SELECTxCol.value('(//author/last-name)[1]','nvarchar(50)')LastNameFROMdocs

通过求node()-value()组合的值来提取属性值可以不需要顺序规范,如下一个示例所示。

例:已知的singleton元素

如下所示的nodes()方法为每个<book>元素生成单独的行。对<book>节点求值的value()方法提取@genre的值,@genre作为一个属性,是singleton元素。

SELECTnref.value('@genre','varchar(max)')LastNameFROMdocsCROSSAPPLYxCol.nodes('//book')ASR(nref)

跨域查询

如果数据驻留在关系数据类型的列和XML数据类型的列的组合中,就可能需要编写查询来组合关系数据处理和XML数据处理。通过使用带有TYPE指令的FORXML,可以将关系列和XML列中的数据转换成XML数据类型的实例,并使用XQuery对其进行查询。相反地,可以从XML值生成行集,并且使用T-SQL来对其进行查询,如下面的“从XML数据生成行集”一节所示。

编写跨域查询的一个更加方便和有效的方法是,使用SQL变量的值,或者使用XQuery或XML数据修改表达式中的列:

使用sql:variable(),可以在XQuery或XMLDML表达式中应用SQL变量的值。

通过sql:column(),可以在XQuery或XMLDML上下文中使用来自关系列的值。

这种方法允许应用程序参数化查询,如下面的示例所示。Sql:column()的用法与前者类似,并且还带来其他的好处。正如基于成本的查询优化器所确定的,可以使用列的索引来提高效率。此外,也可以使用计算列。

XML和用户定义的类型不允许与sql:variable()sql:column()一起使用。

例:使用sql:variable()的跨域查询

在这种查询中,<book>元素的ISBN是使用SQL变量@isbn来传入的。代替使用常量,sql:variable()提供ISBN的值,并且该查询可以用于搜索任何ISBN,而不只是ISBN为0-7356-1588-2的元素。

DECLARE@isbnvarchar(20)SET@isbn='0-7356-1588-2'SELECTxColFROMdocsWHERExCol.exist('/book[@ISBN=sql:variable("@isbn")]')=1

从XML数据生成行集

在自定义属性管理和数据交换场景中,应用程序通常将XML数据的某些部分映射到行集。例如,为了将输入参数表传送到存储过程或函数,应用程序需要将数据转换成XML,并且将其作为XML数据类型的参数传入。在存储过程或函数中,行集是从XML参数生成的。

SQLServer2000为此提供了OpenXml()。它简化了从XML实例生成行集的过程,方法是指定行集的关系架构以及将XML实例内的值映射到行集中的列的方式。

另外,还可以使用nodes()方法来生成XML实例中的节点上下文,并且在value()query()exist()nodes()方法中使用该节点上下文来生成所期望的行集。nodes()方法接受XQuery表达式,在XML列的每个XML实例中对其进行求值,并且有效地使用XML索引。下一个示例演示如何将nodes()方法用于行集生成。

例:从XML实例提取属性

假定要提取名字不是“David”的作者的名和姓,将其作为由两列(FirstName和LastName)组成的一个行集。通过使用nodes()value()方法,您可以达到此目的,如下所示:

SELECTnref.value('first-name[1]','nvarchar(50)')FirstName,nref.value('last-name[1]','nvarchar(50)')LastNameFROMdocsCROSSAPPLYxCol.nodes('//author')ASR(nref)WHEREnref.exist('.[first-name!="David"]')=1

在这个示例中,nodes('//author')产生一个指向每个XML实例的元素的引用的行集。作者的名和姓是通过对与这些引用有关的value()方法求值来获得的。要获得好的性能,需要建立XML列的索引,这是下一部分的主题。

建立XML数据的索引

XML数据是以内部二进制形式存储的,存储容量可以达到2GB。每个查询在运行时一次或多次地解析表中每一行的XMLBLOB。这会使查询处理的速度变得很慢。如果在工作负荷中常常需要进行查询,则建立XML列的索引是有好处的,不过,这样做必须考虑在修改数据的过程中维护XML索引的成本。

XML索引是通过一个新的DDL语句在类型化和非类型化的XML列中创建的。这为该列中的所有XML实例创建了一个B+树。XML列中的第一个索引是“主XML索引”。通过这个索引,可以在XML列中支持三种类型的次XML索引来加速普通类的查询,如下一节所述。

主XML索引

在基表(即定义XML列的表)的主键中,主XML索引需要聚集索引。它在XML节点的信息集项的一个子集中创建一个B+树。B+树的列表示标记,例如元素和属性名称、节点值和节点类型。其他的列捕获XML数据中的文档顺序和结构,以及从XML实例的根节点到每个节点的路径,从而有效地对路径表达式进行求值。基表的主键在主XML索引中复制,以使索引行与基表行相关。

XML架构中给定的标记和类型名称被映射为整数值,而映射值存储在B+树中以优化存储。索引中的路径列按照相反的顺序(即从节点到XML实例的根)存储映射值的串联。当路径后缀已知时(在一个路径表达式中,如//author/last-name),相反的表示使得可以匹配路径值。

如果对基表进行分区,则需要以相同的方式对主XML索引进行分区,也就是使用相同的分区函数和分区架构。

全部的XML实例都是从XML列检索的(SELECT*FROMdocs或SELECTxColFROMdocs)。需要XML数据类型方法的查询使用主XML索引,从索引本身返回标量值或XML子树。

例:创建主XML索引

下面的语句在表docs的XML列xCol中创建一个名为idx_xCol的XML索引。

CREATEPRIMARYXMLINDEXidx_xColondocs(xCol)

次XML索引

一旦主XML索引创建完毕,就可以创建次XML索引来加速工作负荷中不同类的查询。三种类型的次XML索引—PATH、PROPERTY和VALUE—分别对基于路径的查询、自定义属性管理方案和基于值的查询有利。

PATH索引在主XML索引的列(path,value)中构建B+树。该路径的值是通过计算路径表达式和节点的值得出的,如果提供了一个路径值,则也可以使用所提供的值。在已知PATH索引开始字段的情况下,查找PATH索引可以加速路径表达式的求值。最常见的情况是在SELECT语句的WHERE子句中对XML列使用exist()方法。

PROPERTY索引在主XML索引的列(PK,path,value)中创建B+树,其中PK是基表的主键。此索引对XML实例中的属性值查找有利。

最后,VALUE索引在主XML索引的列(value,path)中创建一个B+树。此索引对节点的值已知但是其路径没有准确地在查询中指定的查询有利。这通常出现在祖先或自身(descendant-or-self)轴查询中,例如,//author[last-name="Howard"],其中,元素可以出现在层次的任何一层。它还可以出现在“wildcard”查询中,例如/book[@*="novel"],其中,查询查找具有“novel”属性值的元素。此外,VALUE索引还可用于对类型化的XML进行基于值的范围扫描。

可以容纳多达128层的XML层次;在插入和修改的过程中,如果XML实例包含更长的路径,则会被拒绝。

类似地,可以建立一个节点值的前128个字节的索引;系统中可以容纳更长的值,但是不会建立索引。

例:基于路径的查找

假定下面的查询在工作负荷中是常见的:

SELECTxColFROMdocsWHERExCol.exist('/book[@genre="novel"]')=1

路径表达式/book/@genre和值“novel”对应于PATH索引的键字段。因此,类型PATH的次XML索引有助于此工作负荷:

CREATEXMLINDEXidx_xCol_Pathondocs(xCol)USINGXMLINDEXidx_xColFORPATH

例:获取对象的属性

考虑下面的查询,它从表T的每一行检索书的“genre”、“title”和ISBN属性:

SELECTxCol.value('(/book/@genre)[1]','varchar(50)'),xCol.value('(/book/title)[1]','varchar(50)'),xCol.value('(/book/@ISBN)[1]','varchar(50)')FROMdocs

属性索引可用于这种情况,该索引创建如下:

CREATEXMLINDEXidx_xCol_Propertyondocs(xCol)USINGXMLINDEXidx_xColFORPROPERTY

例:基于值的查询

在下面的查询中,祖先或自己轴(//)指定了部分路径,这样,基于ISBN值的查询就可以从VALUE索引的使用中受益:

SELECTxColFROMdocsWHERExCol.exist('//book[@ISBN="1-8610-0157-6"]')=1

VALUE索引创建如下:

CREATEXMLINDEXidx_xCol_Valueondocs(xCol)USINGXMLINDEXidx_xColFORVALUE

内容索引

可以在XML列中创建全文本索引;这会建立XML值内容的索引而忽略XML标记。属性值不是全文本索引的(因为它们被认为是标记的一部分),而元素标记被用作标记边界。可以在XML列中创建XML和全文本索引,并且组合使用全文本搜索和XML索引。使用全文本索引作为第一个筛选器来缩小选择范围,接着再应用XQuery进一步筛选。

使用CONTAINS()和XQuerycontains()的全文本搜索有不同的语义。后者是子字符串匹配,而前者是使用词根检索的标记匹配。

例:在XML列中创建全文本索引

在XML列中创建全文本索引的步骤与在其他SQL类型列中创建全文本索引的步骤是非常相似的。需要在基表中有一个唯一的键列。DDL语句如下,其中,PK__docs__7F60ED59是该表的单列主键索引:

CREATEFULLTEXTCATALOGftASDEFAULTCREATEFULLTEXTINDEXONdbo.docs(xCol)KEYINDEXPK__docs__7F60ED59

例:组合全文搜索和XML查询

下面的查询检查XML值是否在书的标题中包含单词“Secure”:

SELECT*FROMdocsWHERECONTAINS(xCol,'Secure')ANDxCol.exist('/book/title/text()[contains(.,"Secure")]')=1

CONTAINS()方法使用全文本索引来产生一个XML值的子集,它包含文档中所有的单词“Secure”。exist()子句确保单词“Secure”出现在书的标题中。

使用XML索引执行查询

XML索引可以加速查询的执行。查询总是针对XML列中的主XML索引进行编译(如果存在的话)。为整个查询(包括关系部分和XML部分)制订一个查询计划,该计划可以通过数据库引擎基于成本的优化器进行优化。根据查询优化器的成本估算来选择次XML索引。

XML索引的目录视图

目录视图用于提供关于XML索引的元数据信息。目录视图sys.indexes包含带有索引“type”3的XML索引项。“name”列包含XML索引的名称。

XML索引也记录在目录视图sys.xml_indexes中,它包含所有的sys.indexes列以及一些对XML索引有意义的特别的列。列“secondary_type”中的值NULL表示主XML索引,值“P”、“R”和“V”分别代表PATH、PROPERTY和VALUE次XML索引。

可以从表值函数sys.fn_indexinfo()中找到XML索引的空间使用。它提供的信息包括所占用的磁盘页数、按字节计算的平均行大小、记录数,以及其他包括XML索引在内的所有索引类型的信息。这些信息可用于每个数据库分区;XML索引使用与基表相同的分区架构和分区函数。

例:XML索引的空间使用

SELECTsum(Pages)FROMsys.fn_indexinfo('docs','idx_xCol_Path',DEFAULT,'DETAILED')

这产生在表T的所有分区中XML索引idx_xCol_Path所占用的磁盘页数。如果没有sum()函数,则结果将会返回每个分区的磁盘页使用。

XML架构处理

在系统中,XML架构是可选的。如前所述,没有绑定到XML架构的XML数据类型被认为是非类型化的;XML节点值将作为Unicode字符串存储,而XML实例需要进行格式良好性检查。可以建立非类型化XML列的索引。

要类型化XML,可以将XML数据类型与已注册到XML架构集合的XML架构相关联。新的DDL语句允许创建一个或多个XML架构可以注册到的XML架构集合。绑定到XML架构集合的XML列、参数或变量是根据该集合中的所有XML架构进行类型化的。在XML架构集合中,类型系统标识每个使用其目标命名空间的XML架构。

XML实例中的每个顶层XML元素都必须指定它遵循的可能为空的目标命名空间。在插入和修改数据时,将根据每个顶层元素的目标命名空间对其进行有效性检查。二进制XML表示根据相关的XML架构信息对类型化值进行编码,并且是完整描述的,因此,与非类型化的XML相比,它的再解析效率更高一些。在XML索引中,还将对值进行适当的类型化(如果/book/price是在像xs:decimal这样的命名空间中定义的,则会存储为小数)。

在查询编译的过程中,使用XML架构进行类型检查,并且会因类型不匹配而引起静态错误。查询编译器还将XML架构用于查询优化。

数据库引擎的元数据子系统包含XML类型信息,例如XML架构集合和它们所包含的XML架构,以及基本XSD和关系类型系统之间的映射。几乎所有的W3CXML架构1.0规范(请参阅http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/和http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/)都支持。XML架构文档中的注释和注解都没有保留,并且不支持key/keyref。

XML架构集合

XML架构集合是一个元数据实体(通过关系架构定义作用域),并且包含一个或多个相关(例如,使用<xs:import>))或不相关的XML架构。XML架构集合中单独的XML架构是使用其目标命名空间进行标识的。XML架构集合是安全的实体,大致与表类似。

XML架构集合是使用CREATEXMLSCHEMACOLLECTION语义创建的,提供一个或多个XML架构。然后可以使用XML架构集合来类型化XML列。这种产生了灵活的数据模型,其中,按照不同的XML架构类型化的XML可以存储在相同的列中。当XML架构的数量很大时,这尤其方便。此外,这种设计还支持对XML架构进行一定程度的扩展。

另外,类型化的XML列中的选项DOCUMENT或CONTENT分别指定了XML树或片段是否可以存储在XML列中。默认为CONTENT。对于DOCUMENT,每个XML实例都必须指定其顶层元素的目标命名空间,该XML实例就是按照这个命名空间来进行有效性检查和类型化的。而对于CONTENT,每个顶层元素都可以指定XML架构集合中的任何一个目标命名空间。该XML实例按照出现在实例中的所有目标命名空间进行有效性检查和类型化。

例:创建XML架构集合

假定要使用带有目标命名空间http://myBooks的XML架构来类型化XML实例。可以创建一个XML架构集合myCollection并将该XML架构作为myCollection的内容,如下所示:

CREATEXMLSCHEMACOLLECTIONmyCollectionAS'<xsd:schemaxmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://myBooks"elementFormDefault="qualified"targetNamespace="http://myBooks"><xsd:elementname="bookstore"type="bookstoreType"/><xsd:complexTypename="bookstoreType"><xsd:sequencemaxOccurs="unbounded"><xsd:elementname="book"type="bookType"/></xsd:sequence></xsd:complexType><xsd:complexTypename="bookType"><xsd:sequence><xsd:elementname="title"type="xsd:string"/><xsd:elementname="author"type="authorName"/><xsd:elementname="price"type="xsd:decimal"/></xsd:sequence><xsd:attributename="genre"type="xsd:string"/><xsd:attributename="publicationdate"type="xsd:string"/><xsd:attributename="ISBN"type="xsd:string"/></xsd:complexType><xsd:complexTypename="authorName"><xsd:sequence><xsd:elementname="first-name"type="xsd:string"/><xsd:elementname="last-name"type="xsd:string"/></xsd:sequence></xsd:complexType></xsd:schema>'

同时也为该XML架构注册到的myCollection创建了一个新的元数据实体。

修改XML架构集合

ALTERXMLSCHEMACOLLECTION语句支持用新的顶层架构组件来扩展XML架构,并且还支持将新的XML架构注册到XML架构集合。下面的示例对此进行了演示。

例:改变XML架构集合

下面的语句显示了如何将具有目标命名空间http://myDVD的新XML架构添加到XML架构集合myCollection中:

ALTERXMLSCHEMACOLLECTIONmyCollectionADD'<xsd:schemaxmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://myDVD"elementFormDefault="qualified"targetNamespace="http://myDVD"><xsd:elementname="dvdstore"type="dvdstoreType"/><xsd:complexTypename="dvdstoreType"><xsd:sequencemaxOccurs="unbounded"><xsd:elementname="dvd"type="dvdType"/></xsd:sequence></xsd:complexType><xsd:complexTypename="dvdType"><xsd:sequence><xsd:elementname="title"type="xsd:string"/><xsd:elementname="price"type="xsd:decimal"/></xsd:sequence><xsd:attributename="genre"type="xsd:string"/><xsd:attributename="releasedate"type="xsd:string"/></xsd:complexType></xsd:schema>'

XML架构集合的目录视图

XML架构集合的SQL目录视图允许用户重新构造单独的XML架构命名空间的内容。XML架构集合在目录视图sys.xml_schema_collections中枚举。XML架构集合“sys”由系统定义,并且包含一些预定义的命名空间,这些命名空间可用于所有用户定义的XML架构集合,而不必显式地加载它们。该列表包含用于xml、xs、xsi、fn和xdt的命名空间。

值得一提的其他两个目录视图是:sys.xml_schema_namespaces,它枚举每个XML架构集合中的所有命名空间;sys.xml_components,它枚举每个XML架构中的所有XML架构组件。

内置函数XML_SCHEMA_NAMESPACE()接受关系架构和XML架构集合的名称,以及XML架构的目标命名空间(可选)。它返回包含该XML架构的XML数据类型实例。如果目标命名空间参数被省去,那么该内置函数返回的XML实例就会包含XML架构集合中除预定义XML架构以外的所有XML架构。

例:枚举XML架构集合中的XML命名空间

将下列查询用于XML架构集合“myCollection”:

SELECTXSN.nameFROMsys.xml_schema_collectionsXSCJOINsys.xml_schema_namespacesXSNON(XSC.xml_collection_id=XSN.xml_collection_id)WHEREXSC.name='myCollection'

例:从XML架构集合输出指定的XML架构

下面的语句从(关系)架构dbo中的XML架构集合“myCollection”输出带有目标命名空间http://myBooks的XML架构。

SELECTXML_SCHEMA_NAMESPACE(N'dbo',N'myCollection',N'http://myBooks')

对XML架构集合的访问控制

通过使用SQLServer2005的安全模型,可以像任何SQL对象一样保护XML架构集合。您可以授予用户在数据库中创建XML架构集合的特权。每个XML架构集合都支持ALTER、CONTROL、TAKEOWNERSHIP、REFERENCES、EXECUTE和VIEWDEFINITION等权限。

执行ALTERXMLSCHEMACOLLECTION语句需要ALTER权限。

如果要通过执行ALTERAUTHORIZATION语句将XML架构集合的所有权从一个用户转移到另一个用户,则需要TAKEOWNERSHIP权限。

REFERENCES权限授权用户在任何需要架构绑定的地方使用XML架构,例如,类型化或约束XML列和参数。

要检查用户针对XML架构集合插入或更新的值的有效性,则需要EXECUTE权限。使用XML数据类型从类型化的XML列、变量和参数查询值也需要此权限。

VIEWDEFINITION权限允许用户访问目录视图中与XML架构集合(所有的XML架构都包含其中)对应的行,所有XML架构组件都包含在这些XML架构中。

CONTROL权限授予用户执行XML架构集合中任何操作的权限,包括使用DROPXMLSCHEMACOLLECTION语句撤消XML架构集合。这意味着具有XML架构集合的其他权限。

除了表或XML列中的其他权限以外,还需要XML架构集合的权限。用户需要权限来创建表,并且还需要XML架构集合C中的REFERENCES权限来创建包含XML列X(按照C类型化)的表T。具有将数据插入列X的权限的用户可以这样做,前提是用户具有XML架构集合C中的EXECUTE权限。类似地,要使用XML数据类型方法来查询列X中的数据,用户需要列X中的SELECT权限和列C中的EXECUTE权限。然而,对于从列X检索整个XML值,列X中的SELECT权限就足够了,例如SELECTXFROMT或SELECT*FROMT。

可以从用户撤回权限,还可以通过SQLServer2005的安全模型拒绝用户的权限,正如允许其拥有权限一样。

目录视图的可视化

XML架构集合中具有ALTER、TAKEOWNERSHIP、REFERENCES、VIEWDEFINITION或CONTROL权限的用户可以在目录视图中访问XML架构集合的行及其所包含的XML架构和它们的XML架构组件。该主体还可以通过使用内置函数XML_SCHEMA_NAMESPACE()来访问XML模式集合的内容。

如果用户的VIEWDEFINITION权限被拒绝,则该用户就不能在目录视图中或通过使用XML_SCHEMA_NAMESPACE()访问XML架构集合。

对FORXML的增强

可以将TYPE指令生成的XML数据类型实例分配给XML列、变量或参数,或者使用XML数据类型方法对其进行查询。这使得可以嵌套SELECT...FORXMLTYPE语句。

PATH模式允许用户指定需要出现列值的XML树中的路径,并且与上述嵌套一起使用时更易于编写(与FORXMLEXPLICIT相比),不过,它也不可用于深层次。

与ELEMENTS一起使用的指令XSINIL可以将NULL映射为具有属性xsi:nil="true"的元素。新的ROOT指令允许在所有的FORXML模式下指定根节点。新的XMLSCHEMA指令生成XSD内联架构。

要获得更多关于改进和示例的信息,请参阅由MichaelRys撰写的“What'sNewinFORXMLinMicrosoftSQLServer”(MSDN于2004年6月发布)。

性能指导原则

XML数据模型比关系数据模型更加丰富,因而也更加复杂。XML数据模型不仅允许对复杂的数据进行建模,而且还必须保留层次关系和数据中的文档顺序。文档顺序是通过基于XML节点标识符的排序维护的;这同时维护了层次关系。所有这些都对更复杂的查询计划产生了影响。

为了获得更好的性能,应该将结构化数据存储在表的关系列中。如果数据是半结构化或非结构化的,则需要选择使用XML数据模型来进行建模,并且加入XML标记,不过,别指望会有什么好的性能。XML架构有助于查询优化。

SQLServerCLR中的XML支持

通过使用SQLServerCLR支持,可以在托管代码中编写服务器端逻辑来执行业务规则。可以采用多种方法来将这些业务逻辑添加到XML数据中:

可以在XML值传入的托管代码中编写SQLCLR函数,并且使用System.Xml命名空间提供的XML处理功能。这样的一个例子是将XSL转换应用于XML数据,如下所述。另外,还可以将XML反序列化成一个或多个托管类,并且使用托管代码对它们进行操行。

可以编写T-SQL存储过程和函数来调用XML列中的处理,以满足您的业务需要。

例:应用XSL转换

考虑接受XML数据类型实例的CLR函数TransformXml()和存储在文件中的XSL转换,将该转换应用到XML数据,并返回已转换的XML结果。用编写的主干函数如下:

publicstaticSqlXmlTransformXml(SqlXmlXmlData,stringxslPath){//LoadXSLtransformationXslTransformxform=newXslTransform();XPathDocumentxslDoc=newXPathDocument(xslPath);xform.Load(xslDoc.CreateNavigator(),null);//LoadXMLdataXPathDocumentxDoc=newXPathDocument(XmlData.CreateReader());XPathNavigatornav=xDoc.CreateNavigator();//ReturnthetransformedvalueSqlXmlretSqlXml=newSqlXml(xform.Transform(nav,null));return(retSqlXml);}

一旦注册了程序集并创建了用户定义的T-SQL函数SqlXslTransform()(与TransformXml()相对应),就可以从T-SQL调用该函数,如下面的查询所示:

SELECTSqlXslTransform(xCol,'C:/yukon/xsltransform.xsl')FROMTWHERExCol.exist('/book/title/text()[contains(.,"custom")]')=1

查询结果包含已转换的XML的行集。

SQLCLR开辟了一个全新的世界,可用于将XML数据分解成表或属性提升,并且使用System.Xml命名空间中的托管类来查询XML数据。更多的信息可以在SQLServer2005和VisualStudio?2005在线书籍中找到。

返回页首

SQLServer2005中的客户端XML处理

XML数据类型的客户端支持

.NET框架V2.0中的ADO.NETXML支持

SqlDataReader.GetSqlXml()方法的System.Data.SqlTypes命名空间中,XML数据类型是作为类SqlXml公开的。可以使用SqlXml.CreateReader()函数从SqlXml对象获得XmlReader。

类型化XML列的XML架构集合的名称由三部分组成,可以从XML列的元数据中获得(通过使用SqlDataReader对象中的GetSchemaTable()或GetSqlMetaData(int)),其三个部分作为三个属性,分别表示数据库(XmlSchemaCollectionDatabase)、关系架构(XmlSchemaCollectionOwingSchema)和XML架构集合(XmlSchemaCollectionName)的名称。

客户端可以使用新的架构行集XMLSCHEMA从服务器检索XML架构。XMLSCHEMA行集包含XML架构集合、目标命名空间和XML架构内容本身这样三列。

下面的示例显示了用于对XML数据类型进行托管访问的主干代码。

例:对XML数据类型进行进程内访问

下面的C#代码演示了如何从进程内提供程序访问XML数据类型。用于SQL客户端访问的代码需要适当地改变进程内访问。

usingSystem;usingSystem.Xml;usingSystem.Data;usingSystem.Data.SqlTypes;usingSystem.Data.SqlServer;classxmldtADONETReadInProc{staticvoidReadXmlDataType(){//in-procconnectiontoserverSqlConnectionconn=SqlContext.GetConnection();//preparequerytoselectxmldataSqlCommandcmd=conn.CreateCommand();cmd.CommandText="SELECTxColFROMdocs";//executequeryandretrieveincomingdataSqlDataReaderr=cmd.ExecuteReader();r.Read();//accessXMLdatatypefieldinrowsetSqlXmlxml=r.GetSqlXml(0);newXmlTextWriter(Console.Out).WriteNode(xml.CreateReader(),true);}}

例:使用SQL客户端提供程序更新XML数据类型列

下面的代码所显示的WriteXmlDaraType()方法使用SQL客户端程序提供程序来替换XML列中的值。用于进程内提供程序的代码是相似的。

usingSystem;usingSystem.Xml;usingSystem.Data;usingSystem.Data.SqlTypes;usingSystem.Data.SqlClient;classxmldtADONETUpdateAccess{staticvoidWriteXmlDataType(){//connectiontoserverSqlConnectionconn=newSqlConnection("server=server1;"+"database=XMLtest;IntegratedSecurity=SSPI");conn.Open();//updateXMLcolumnattheserverSqlCommandcmd=conn.CreateCommand();cmd.CommandText="UPDATEdocsSETxCol=@xWHEREid=1";//setvalueofXMLparameterSqlParameterp=cmd.Parameters.Add("@x",SqlDbType.Xml);p.Value=newSqlXml(newXmlTextReader("<hello/>",XmlNodeType.Document,null));//executeupdateandcloseconnectioncmd.ExecuteNonQuery();conn.Close();}}

SQL本机客户端访问

在新的SQL本机访问(SQLNCLI)的OLEDB提供程序中,可以通过ISequentialStream来将XML数据类型列作为Unicode字符串(DBTYPE_XML、DBTYPE_BSTR、DBTYPE_WSTR和DBTYPE_VARIANT)或Unicode字符串流进行检索。默认为DBTYPE_XML。

由三部分组成的XML架构集合名称是在由IDBSchemaRowset::GetRowset()返回的COLUMNS架构行集的三个新列中携带的:SS_XML_CATALOGNAME给出目录的名称;SS_XML_SCHEMANAME给出XML架构集合所驻留的关系架构的名称;SS_XML_SCHEMACOLLECTIONNAME给出XML架构集合的名称。这些名称都属于DBTYPE_WSTR类型。对于非类型化的XML列,这些列具有NULL值。

可以对PROCEDURE_PARAMETERS架构行集和IColumnRowset:GetColumnRowset()进行类似的改变。

要检索XML架构集合的内容,客户端可以通过在对XML_SCHEMA_NAMESPACE()的调用中使用这些名称来单独访问服务器,并且返回XML架构作为XML数据类型。另外,带有新的SS_XMLSCHEMA架构行集的IDBSchemaRowset可以返回目录的名称、关系架构的名称、XML架构集合的名称、目标命名空间和XML架构。

要使用SQLNCLI进行ODBC访问,需要将XML数据类型映射到名为SQL_SS_XML的Unicode可变长度字符数据。由三部分组成的XML架构集合的名称是通过用于XML列的SqlColAttribute作为CharacterAttributePtr出现的。这些字段标识符为SQL_DESC_SS_XML_SCHEMA_CATALOG_NAME、SQL_DESC_SS_XML_SCHEMA_SCHEMA_NAME和SQL_DESC_SS_XML_SCHEMA_COLLECTION_NAME,分别用于数据库、关系架构和XML架构集合的名称。

用户必须安装SQLServer2005版的数据库服务器或客户端工具才能获取SQL本机客户端。在撰写本文时,还不能使用MDAC2.8ADO对XML数据类型进行OLEDB访问。

SQLXML—XML和关系架构之间的映射

可以使用SQLXML映射技术来创建关系数据的逻辑XML视图。XML视图(也称为“映射”或“带注解的架构”)是通过将特殊的注解添加到特定的XSD架构中创建的。于是,其他的SQLXML技术就可以使用这种带注解的架构,将针对逻辑XML视图进行的查询和更新转换成针对关系表进行的查询和更新:

当XML视图与XPath查询组合在一起时,SQLXML将生成FORXML查询来查找请求数据,并且根据架构的指定对其进行构形。

SQLXMLUpdategrams表示对XML实例进行的更改,当与带注解的架构组合在一起时,将使用开放式并发将这些更改重新保存到关系更改中,以确保更新正确的数据。

SQLXMLBulkload使用XML视图将XML数据“切碎”并存放到关系表中。

有关这些主题的更多信息,请访问SQLXMLdocumentation。

创建关系表的XML视图

要创建数据库的XML视图,需要从用于XML数据的XSD架构开始。数据库表/视图中的行将映射为该架构中复杂类型的元素。数据库中的列值映射为属性或简单类型的元素。

默认情况下,如果没有给出显式注解,SQLXML就会假定复杂类型的元素将映射到表,而简单类型的元素和属性将映射到列。只有当元素和属性的名称与数据库中表和列的名称完全相同时,这才有效。

如果元素/属性的名称与它映射到的表/视图或列的名称不同,则必须创建显式映射。下面的注解用于指定XML文档中的元素或属性间的映射和数据库中的表(视图)或列之间的映射:

sql:relation—将XML元素映射到数据库表。

sql:field—将元素或属性映射到数据库列。

通过映射关系创建XML视图中的层次

在数据库中,表可以通过外键关系来关联。在XML中,这些相同的关系是通过嵌套的元素层次来表示的。为了在映射中构造正确的嵌套,必须指定关联元素的方式。可以使用sql:relationship注解在映射架构元素中建立这些关系。在这种注解中,可以指定父表和子表,以及每个表中需要用于执行加入的列。然后,SQLXML将利用这些信息为映射构造正确的嵌套层次。

使用溢出存储未使用的数据

当XML数据有正规的结构时映射是有效的。然而,在XML中,可能有一些数据是非结构化的,还可能有一些数据没有映射到特定的列。要存储这种数据并随后检索它,可以使用sql:overflow注解。sql:overflow注解指定存储所有未使用数据的列以及查询时从何处检索数据。

通过溢出列,还可以扩展XML,而不必将其添加到数据库。可以在任何时候将元素和属性添加到XML结构,而不必在数据库中添加列来存储它们。可以将它们简单地存储到溢出字段,并且在适当的时候对其进行检索。

更多信息

有关创建XML视图和映射示例的详细信息,请参阅CreatingXMLViewsbyUsingAnnotatedXSDSchemas。

使用XPath来查询XML视图

一旦创建好数据库的XML视图,就可以使用XPath查询语言来查询视图,就好像它是实际的XML文档一样。SQLXML支持XPath1.0查询语言中的一个子集。当针对映射进行XPath查询时,SQLXML将它们组合在一起,并且创建发送到SQLServer的FORXMLEXPLICIT语句。然后检索正确的数据,并根据映射对其进行构形。

请参阅SQLXML文档以获得关于XML视图中支持的XPath子集的详细信息。

使用Updategrams通过XML视图进行更新

可以通过XML视图修改(插入、更新或删除)SQLServer中的数据库,方法是针对数据库的XML视图使用Updategram。

updategram的结构

updategram是一个XML文档,带有<sync>、<before>和<after>元素,这些元素构成了updategram的语法。每个<sync>块包含一个或多个<before>和<after>块。<before>标识记录实例的现有状态(也称为“前状态”)。<after>标识要更改的数据的新状态。updategram是删除、插入还是更新记录实例取决于<before>和<after>块的内容。

插入操作

当记录实例出现在<after>块而没有出现在相应的<before>块中时,updategram指示插入操作。在这种情况下,updategram将<after>块中的记录插入数据库。

删除操作

当记录实例出现在<before>块而没有相应的记录出现在<after>块中时,updategram指示删除操作。在这种情况下,updategram从数据库中删除<before>块中的记录。

如果在updategram中指定的元素或者匹配表中的多行或者不匹配表中的任何行,则updategram会返回错误,并取消整个<sync>块。updategram中的元素一次只能删除一条记录。

更新操作

当更新现有的数据时,必须指定<before>和<after>块。updategram使用<before>块中指定的元素来标识数据库中的现有记录。<after>块中相应的元素指示在执行更新操作之后记录的外观应该怎样。

<before>块中的元素必须只与数据库中的一个表行相匹配。如果该元素匹配多个表行或不匹配任何表行,则updategram都会返回错误,并且取消整个<sync>块。

更多信息

要获得更多关于通过XML视图创建和使用updategram修改数据的信息,请参阅UsingUpdategramstoModifyData。

通过XML视图大量加载XML数据

XMLBulkLoad是一个COM对象,它允许您将XML数据加载到SQLServer表中。虽然通过使用INSERT语句和OPENXML函数可以将XML数据插入SQLServer数据库中,但是当需要插入大量的XML数据时,这种大量加载实用程序提供了更高的性能。XMLBulkLoad解释映射架构并标识XML数据要插入的表。然后,它将XML数据“切碎”并存放到关系表中。

在进行大量加载处理时,由于源XML文档可能很大,所以并不将整个文档读入内存。相反,XMLBulkLoad将XML数据解释为流,并且边解释它边读取它。当该实用程序读取数据时,它标识数据库表,从XML数据源生成适当的记录,然后将记录发送到SQLServer,以供插入。

要获得更多关于BulkLoad如何工作和使用的信息,请参阅PerformingBulkLoadofXMLData。

SQLXML数据访问方法

由于有了SQLServer2000,所以又增加了两种访问SQLXML功能的新方法:

SQLXML托管类

SQLXMLWeb服务

另外,还增强了对SQLServer的HTTP访问,以提供对模板中的Updategram的支持

SQLXML托管类

SQLXML托管类公开Microsoft.NET框架内的SQLXML3.0的功能。通过SQLXML托管类,可以编写C#应用程序从SQLServer的实例访问XML数据,将数据带入.NET框架环境,处理数据,并将更新重新发送回SQLServer以应用这些更新。

要获得更多关于如何使用SQLXML托管类的细节,请参阅SQLXML.NETSupport。

SQLXMLWeb服务

SQLXML中的Web服务支持将SQLServer作为Web服务公开,从而为客户端提供SQLServer功能。可以将SOAPHTTP请求发送到正在运行SQLXML的服务器,以执行存储过程、用户定义的函数(UDF)和模板。

通过使用所包括的用于SQLServer实用程序的IIS虚拟目录管理,也可以设置Web服务。一旦Web服务虚拟目录设置完毕,就可以将存储程序和模板添加到站点。然后,客户端就可以通过HTTP之上的SOAP来访问这些服务。

SQLServer2005现在包括对服务器中的Web服务的本机支持。然而,只有SQLXML支持通过Web服务访问XML模板。另外,可以在不同于数据库服务器的服务器上设置SQLXML,创建远离数据库的单独中间层盒子。

要获得更多关于SQLXMLWeb服务的细节,请访问WebServices(SOAP)SupportinSQLXML。

.NET框架2.0中的XQuery

为了在SQLServer2005中补充引入XQuery,在VisualStudio2005Beta的.NET框架V2.0版中,System.Xml.Query命名空间内置了一个中间层XQuery处理器。在这一部分中,我们说明该处理器如何提供查询和聚合完全不同的数据源的能力,例如文件和关系数据存储SQLServer数据库。

简单的说,下面的代码示例显示了一个查询,用于选择书店中所有genre属性值为autobiography的书,并且将这些书的标题作为一个新的书店写出。执行查询的称为“books.xml”的本地文件被加载,而将结果写入另一个称为“output.xml”的本地文件。

using(XmlWriterwriter=XmlWriter.Create("output.xml")){XQueryCommandxq=newXQueryCommand();stringquery="<bookstore>"+"{for$sin/bookstore/book"+"where$s/@genre='autobiography'"+"return$s/title}"+"</bookstore>";xq.Compile(query);xq.Execute("books.xml",newXmlUrlResolver(),writer);}

查询表达式如下:

<bookstore>{for$sin/bookstore/bookwhere$s/@genre='autobiography'return$s/title}</bookstore>

XQueryCommand类是XQuery处理器。首先由Compile方法编译查询表达式,该方法对值进行类型检查,并且生成一个可执行文件。Execute方法执行接受books.xml文档作为输入的查询。

在SQLServer(具有将T-SQL语句内嵌到XQuery表达式的功能)中,XQueryCommand类还能够对关系表中的数据进行查询。事实上,这使得能够将两个不同的查询语言之间的集成运用于不同的域,并且还补充了反向SQLServer2005,其中,T-SQL语句内嵌到XQuery语句。下面的代码示例显示了一个查询,用于从样本Northwind数据库中选择所有的顾客。

declarenamespacesql='http://schemas.Microsoft.com/framework/2003/xml/sql';<Customers>{$for$customerinsql:query("select*fromcustomers","conn")/*returncustomer}</Customers>

sql:query方法使您能够对连接进行T-SQL查询,其结果以与XQuerydoc()函数完全相同的风格作为XML文档返回。如果结果是由关系类型组成的,则在客户端作为有效流转换成XML。如果SQL查询的结果已经是XML,例如FORXML查询或XML数据类型的查询,则使用该查询的结果。如果没有返回结果,像在大多数T-SQLDML语句的情况下,这解释为空文档,它是有效的。来自此XQuery的输出如下所示,它列出了用Customers元素包装的顾客表中所有的顾客。在结果中自动为表中的每一行创建行元素。

<Customers><row><CustomerID>ALFKI</CustomerID><CompanyName>AlfredsFutterkiste</CompanyName><ContactName>MariaAnders</ContactName><ContactTitle>SalesRepresentative</ContactTitle><Address>ObereStr.57</Address><City>Berlin</City><PostalCode>12209</PostalCode><Country>Germany</Country><Phone>030-0074321</Phone><Fax>030-0076545</Fax></row><row><CustomerID>ANATR</CustomerID><CompanyName>AnaTrujilloEmparedadosyhelados</CompanyName><ContactName>AnaTrujillo</ContactName><ContactTitle>Owner</ContactTitle><Address>Avda.delaConstitucion2222</Address<City>MexicoD.F.</City<PostalCode>05021</PostalCode><Country>Mexico</Country><Phone>(5)555-4729</Phone><Fax>(5)555-3745</Fax></row>...</Customers>

为了通过SQLServer执行此查询,需要使用下面的代码。

staticStringConnectionString="database=Northwind;DataSource=localhost;IntegratedSecurity=SSPI";using(SqlConnectionconnection=newSqlConnection(ConnectionString)){XmlDataSourceResolverresolver=newXmlDataSourceResolver();resolver.Add("conn",connection);XQueryCommandxq=newXQueryCommand();StreamReaderreader=newStreamReader("query.xml");xq.Compile(reader);XmlWriterSettingssettings=newXmlWriterSettings();settings.Indent=true;settings.ConformanceLevel=ConformanceLevel.Auto;using(XmlWriterwriter=XmlWriter.Create("output.xml",settings)){try{connection.Open();xq.Execute(resolver,writer);}catch(Exceptione){Console.Out.WriteLine(e.Message);Console.Out.WriteLine(e.InnerException.Message);}}}

这里,XmlDataSourceResolver类提供使数据库连接与sql:query调用内可以使用的名称相关联的角色。首先从名为query.xml的本地文件中读取该查询,再进行编译,然后创建XmlWriter来写入结果。需要注意XmlWriter中使用的ConformanceLevel.Auto设置,它自动检测创建片段还是创建文档,这是必要的,因为可以借此构造结果中的元素,XQuery能够生成这两者。在执行查询之前,向数据库打开连接,然后执行查询,并将结果写入文件。

sql:query命令极其灵活而强大,它能够将有名称的参数提供给服务器上的T-SQL查询或调用的存储过程。sql:query中命名的参数的作用完全等同于System.Data.SqlClient类。参数是在T-SQL查询中提供的,由后面紧跟名称的“@”表示。然后提供该名称和实际值之间的绑定作为查询的参数。对于每个命名的值,可以将相应的值(由序列中的位置决定)用于绑定。必须有与语言绑定数量相同的参数名称。下面的示例最好地对此进行了演示。

declarenamespacesql='http://schemas.Microsoft.com/framework/2003/xml/sql';let$country:="USA"<Customers>{for$customerinsql:query("select*fromcustomerswhereCountry=@country","conn",{"@country"},{$country})return$customer/PostalCode}</Customers>

这里,将参数country提供给T-SQL查询,从而将$countryXQuery变量绑定到@country参数。结果是所有美国顾客的邮政编码列表。

sql:query函数还可用于调用T-SQL存储过程(如果需要的话,就以上述方式传送参数)。下面的示例显示了如何调用Northwind数据库中的“TenMostExpensiveProducts”存储过程,它没有输入参数。

declarenamespacesql='http://schemas.Microsoft.com/framework/2003/xml/sql';for$prodinsql:query('Exec"TenMostExpensiveProducts"',"conn")return$prod返回页首

小节

本文描述了SQLServer2005中XML的补充技术。服务器端功能包括XML存储、索引和查询处理的本机实现。现有的功能(例如FORXML和OpenXML)已经得到增强。客户端支持包括增强ADO.NET来支持XML数据类型,以及在System.Xml中支持XQuery查询不同的XML源。另外,SQLXML映射技术的Web版增强现在已经合并到SQLServer2005中。

客户端和服务器端支持可用于不同的情况。XML数据类型提供了一种简单的机制来存储XML数据,方法是将XML数据插入非类型化的XML列。使用XML架构定义类型化的XML有助于数据库引擎优化存储和查询处理,另外,还可以提供数据验证。

XML数据类型保留了文档顺序,它对于像文档管理这样的应用程序非常有用。它还可以处理递归的XML架构。对于带有已知架构的结构化数据,关系数据模型仍然是最佳的选择。[n]varchar(max)正好适合于查询和更新不重要的情况。

只要是在服务器上对存储在表中的关系数据使用以XML为中心的编程模型,就可以使用SQLXML映射技术。映射基于将XML架构定义为XML视图。映射可用于将XML数据大量加载到表以及使用XPath1.0来查询表。SQLXML映射技术不保留文档顺序,因此可用于XML数据处理而不是XML文档处理。

在即将发布的.NET框架V2.0Beta1版中,System.Xml内的核心XML类支持读、写、操作和转换XML。通过改进性能、可用性、类型化和查询,V2.0版对XML的支持在创新性、标准支持和易用性方面继续保持行业领先。这包括用于操作SQLServer外的XML源的XQuery处理器在内。

服务器端技术和客户端技术互为补充。映射技术可以利用服务器端功能来增加其功能,例如维护文档顺序和递归架构,以及找到更多的应用领域。另一方面,CLR将可扩展性和现有XML工具(如转换)的价值带入了XML数据类型。服务器和客户端中的XQuery实现彼此之间以及与2003年11月发布的XQuery规范草稿之间都是一致的。XML架构实现在服务器端实现和中间层实现之间也是一致的。

ShankarPalSQLServer引擎的程序经理,主要研究服务器端XML技术。

MarkFussellMicrosoftWebData组的首席程序经理,该小组负责开发Microsof的数据访问技术,其中包括.NET框架的System.XmlSystem.Data命名空间中的组件、MicrosoftXML核心服务(MSXML)以及Microsoft数据访问组件(MDAC)。他的网络日记存放在http://weblogs.asp.net/mfussell

IrwinDolobowsky是Webdata组的程序经理。

<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>