sql2005更新xml_第1页
sql2005更新xml_第2页
sql2005更新xml_第3页
sql2005更新xml_第4页
sql2005更新xml_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、sql 2005 更新xml 分类: SQL相关 2009-10-12 09:59 345人阅读 评论(0) 收藏 举报 1insertinsert用于将Expression1标识的一个或多个节点作为Expression2标识的节点的子节点或同级节点插入。语法格式如下:insert Expression1 ( as first | as last into | after | before Expression2 )Expression1和Expression2 标识要插入的一个或多个节点。它可以是常量XML实例,也可以是XQuery表达式。该表达式可以得出节点、文本节点或一组有序的节点,但它

2、无法解得根节点。如果该表达式得出一个值或一组值,则这些值作为单个文本节点插入,各值之间以空格分隔开。如果将多个节点指定为常量,则这些节点用括号括住,并以逗号分隔开。但无法插入异构序列(如一组元素、属性或值)。如果Expression1解得一个空序列,则不会发生插入操作,并且不会返回任何错误。into Expression1标识的节点作为Expression2标识的节点的子节点插入。如果Expression2中的节点已有一个或多个子节点,则必须使用as first或as last来指定所需的新节点添加位置。after Expression1标识的节点作为Expression2标识的节点的同级节点

3、直接插入在其后面,after关键字不能用于插入属性。before Expression1标识的节点作为Expression2标识的节点的同级节点直接插入在其前面,before关键字不能用于插入属性。(1)插入元素文档中在下面的示例中,首先将XML文档分配给xml类型的变量。然后使用几个insert XML DML语句说明如何将元素节点插入文档中。注意在示例中为各种路径表达式都指定了“1”,以要求每次只返回单个目标,这样就确保了只有单个目标节点。每次插入后,SELECT语句都会显示结果。最终执行结果如图1所示。DECLARE myDoc xml SET myDoc = '<root

4、> <item ID="1"> </item> </root>' SELECT myDoc - 插入item的第1个子节点,此时不需要指定as first或as last SET myDoc.modify('insert <author>张洪举</author> into (/root/item)1') SELECT myDoc- 插入item的第2个子节点,as first指定插入到同级子节点的前面 SET myDoc.modify('insert <title>

5、SQL Server 2005开发宝典</title> as first into (/root/item)1') SELECT myDoc- 插入第2个item节点 SET myDoc.modify('insert <item ID="2"></item> into (/root)1') SELECT myDoc- 向第2个item中插入第1个子节点 SET myDoc.modify('insert <title>SQL Server 2005的新增功能</title> as fi

6、rst into (/root/item)2') SELECT myDoc GO图1 向XML中插入节点(2)插入多个元素到文档中在下面的示例中,将<title>和<author>元素插入到了item节点中。元素之间使用逗号分隔,并包含在括号中。DECLARE myDoc xml SET myDoc = '<root> <item ID="1"> </item> </root>' SELECT myDoc SET myDoc.modify('insert (<tit

7、le>SQL Server 2005开发宝典</title>,<author>张洪举</author>) into (/root/item)1'); SELECT myDoc GO(3)插入属性到文档中在下面的示例中,向XML文档中插入了多个属性。每次插入属性后,SELECT语句都会显示结果,最终执行结果如图2所示。DECLARE myDoc xml SET myDoc = '<root><item ID="1"><title>Ajax实战</title><aut

8、hor>张洪举</author></item></root>' SELECT myDoc SET myDoc.modify('insert attribute ShipTo "广州" into (/root/itemID=1)1'); SELECT myDoc- 通过一个sql变量指定要插入属性ShipDate的值 DECLARE ShipDate char(11) SET ShipDate='2006-01-23Z' SET myDoc.modify('insert attribut

9、e ShipDate sql:variable("ShipDate") cast as xs:date ? into (/root/itemID=1)1') ; SELECT myDoc- 插入多个属性,属性之间使用逗号分隔,并包含在括号内 SET myDoc.modify('insert (attribute PostCode "253020" ,attribute Weight "1.5") into (/root/itemID=1)1'); SELECT myDoc GO图2插入属性到XML中(4)插入注

10、释节点在下面的示例中,将注释节点插入到ID为2的item节点中<title>元素的后面。DECLARE myDoc xml SET myDoc = '<root> <item ID="1"> <title>Ajax实战</title> <author>张洪举</author> </item> <item ID="2"> <title>ASP.NET实战</title> <author>卢桂章</au

11、thor> </item> </root>' SET myDoc.modify('insert <!- 注释 -> after (/root/itemID=2/title)1'); SELECT myDoc GO插入注释后XML的内容如下:<root> <item ID="1"> <title>Ajax实战</title> <author>张洪举</author> </item> <item ID="2&quo

12、t;> <title>ASP.NET实战</title> <!- 注释 -> <author>卢桂章</author> </item> </root>(5)使用CDATA部分插入数据当插入的文本中包含有XML无效字符(如“<”或“>”)时,可以使用CDATA部分插入数据。参考下面的示例:DECLARE myDoc xml SET myDoc = '<root> <item ID="1"> <title>Ajax实战</tit

13、le> <author>张洪举</author> </item> <item ID="2"> <title>ASP.NET实战</title> <author>卢桂章</author> </item> </root>' SET myDoc.modify('insert <desc><!CDATA <送货方式>上门<价款>未收></desc> into (/root/itemI

14、D=2)1 ') ; SELECT myDoc GO被插入部分中的XML无效字符,会被转换成实体,如“<”保存为&lt;。下面的插入CDATA部分后XML文档的内容:<root> <item ID="1"> <title>Ajax实战</title> <author>张洪举</author> </item> <item ID="2"> <title>ASP.NET实战</title> <author>卢

15、桂章</author> <desc> &lt;送货方式&gt;上门&lt;价款&gt;未收</desc> </item> </root>(6)插入文本节点要将文件插入到XML中,需要使用text函数构造文本,参考下面的示例:DECLARE myDoc xml SET myDoc = '<root> <item ID="1"> <title>Ajax实战</title> <author>张洪举</author&g

16、t; </item> </root>' SET myDoc.modify('insert text"订单列表" as first into (/root)1'); SELECT myDoc GO得到的XML结果如下:<root>订单列表<item ID="1"><title>Ajax实战</title><author>张洪举</author></item></root>(7)将节点插入类型化的xml列中在下面的示

17、例中,首先创建了一个架构集合,并建立了一个使用该架构集合的表。在使用Transact-SQL INSERT语句向表中插入一个符合架构约束的XML后,再使用XML DML insert向该XML中插入一个item节点。- 创建XML架构集合 CREATE XML SCHEMA COLLECTION MySchemas AS N'<?xml version = "1.0"?> <xsd:schema targetNamespace=" xmlns:xsd="/2001/XMLSchema"&

18、gt; <xsd:element name="customer"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" name="item"> <xsd:complexType> <xsd:sequence> <xsd:element name="customername" type="xsd:string"/> <xsd

19、:element name="address" type="xsd:string"/> <xsd:element name="phone" type="xsd:string"/> <xsd:element name="contact" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="ID" type="xsd:int"/&g

20、t; </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>' GO - 创建包含xml数据类型列的表 CREATE TABLE MyCustomer (CustomerID int IDENTITY PRIMARY KEY, CustomerItem xml(MySchemas); GO - 向表中插入XML,该XML应当符合 INSERT INTO MyCustomer V

21、ALUES (N'<C:customer xmlns:C=" <item ID="1"> <customername>北方书城</customername> <address>北京市海淀区知春路22号</address> <phone>2222222</phone> <contact>刘先生</contact> </item> </C:customer>'); - 使用XML DML insert插入另一个ite

22、m节点到XML中 UPDATE MyCustomer SET CustomerItem.modify(' declare namespace CS=" insert (<item ID="2"> <customername>东图大厦</customername> <address>长春市朝阳大街99号</address> <phone>1111111</phone> <contact>孙小姐</contact> </item>) into

23、 (/CS:customer)1 ') WHERE CustomerID=1; SELECT CustomerItem FROM Mycustomer; GO执行上面的SELECT查询后,可以看到CustomerItem中的XML内容,如下所示:<C:customer xmlns:C=" <item ID="1"> <customername>北方书城</customername> <address>北京市海淀区知春路22号</address> <phone>2222222<

24、;/phone> <contact>刘先生</contact> </item> <item ID="2"> <customername>东图大厦</customername> <address>长春市朝阳大街99号</address> <phone>1111111</phone> <contact>孙小姐</contact> </item> </C:customer>2deletedelete用于删除X

25、ML实例的节点。其语法格式如下:delete ExpressionExpression是要删除的节点的XQuery表达式。删除该表达式选择的所有节点,以及所选节点中的所有节点或值。表达式不能是根(/)节点。如果表达式返回空序列,则不进行删除,不返回错误。下面的示例演示了从非类型化的xml变量中删除指令、注释、属性、元素和节点的方法。在每次删除后都会显示XML,结果如图3所示。DECLARE myDoc xml SET myDoc = '<?Instructions for=TheWC.exe ?> <root> <!- 这里是注释 -> <it

26、em ID="1" ShipTo="广州">这里是文本 <title>Ajax实战</title> <author>张洪举</author> </item> <item ID="2"> <title>ASP.NET实战</title> <author>卢桂章</author> </item> </root>' SELECT myDoc - 删除注释comment()为去的注释的函

27、数,同样还有text()是去的文本的函数 SET myDoc.modify('delete /root/comment()') SELECT myDoc- 删除所有指令 SET myDoc.modify('delete /processing-instruction()') SELECT myDoc- 删除ID为1的item中的文本节点 SET myDoc.modify('delete /root/itemID=1/text()') SELECT myDoc- 删除一个属性 SET myDoc.modify('delete /root/i

28、temID=1/ShipTo') SELECT myDoc- 删除一个元素 SET myDoc.modify('delete /root/itemID=2/author') SELECT myDoc- 删除ID为2的item节点 SET myDoc.modify('delete /root/itemID=2') SELECT myDoc GO图3从非类型化xml变量中删除注释、指令、属性、元素和节点下面的语句演示从类型化XML中删除节点的方法,其中的MyCustomer是前面在“将节点插入类型化的xml列中”部分中创建的。UPDATE MyCustome

29、r SET CustomerItem.modify('declare namespace CS=" /CS:customer/itemID=2'); SELECT CustomerItem FROM MyCustomer; GO3replacereplace用于更新文档中的值。其语法格式如下:replace value of Expression1 with Expression2Expression1标识其值要更新的节点。它必须仅标识一个单个节点。如果XML已类型化,则节点的类型必须是具有简单类型内容(列表或原子类型)的单个元素、文本节点或属性节点,不能是联合类型、

30、复杂类型、处理指令、文档节点或注释节点。否则,将返回错误。Expression2 标识节点的新值。在修改类型化的XML实例中,Expression2与Expression1必须是相同类型。下面的示例演示了更新XML中元素的文本和属性值的方法。每次更改时,都会显示XML,如图4所示。DECLARE myDoc xml SET myDoc = '<root> <item ID="1"> <title>Ajax实战</title> <author>张洪举</author> </item>

31、<item ID="2"> <title>ASP.NET实战</title> <author>卢桂章</author> </item> </root>' SELECT myDoc - 更新ID为1的item中的title元素的文本 SET myDoc.modify('replace value of (/root/itemID=1/title/text()1 with "Ajax实战攻略"') SELECT myDoc- 更新属性值 SET myD

32、oc.modify('replace value of (/root/itemID=2/ID)1 with "3"') SELECT myDocSQL 2005和XML的那点事儿 分类: SQL相关 2009-10-12 10:50 172人阅读 评论(0) 收藏 举报 XML 数据类型中的方法如果感兴趣,可以检索全部 XML 值,也可以检索部分 XML 实例。这可以使用四个 XML 数据类型的方法来实现:query()、value()、exist() 和 nodes(),它们接受 XQuery 表达式作为参数。第五个方法 modify() 允许修改 XML

33、 数据并接受 XML 数据修改语句作为输入。query() 方法用于提取 XML 实例的部分。XQuery 表达式求值为一个 XML 节点列表。以这些节点中的每一个为根的子树按照文档顺序返回。结果类型为非类型化的 XML。 value() 方法从 XML 实例提取标量值。它返回 XQuery 表达式所求值的节点的值。该值被转换为 value() 方法的第二个参数所指定的 T-SQL 类型。exist() 方法用于对 XML 实例进行存在性检查。如果 XQuery 表达式求值为非空节点列表,则返回 1;否则,返回 0。 nodes() 方法产生特定 XML 数据类型的实例,每个实例都将其上下文设

34、置为 XQuery 表达式所求值的不同节点。特定的 XML 数据类型支持 query()、value()、 nodes() 和 exist() 方法,并且可以用于 count(*) 聚合和 NULL 检查。所有其他的使用都会产生错误。modify() 方法允许修改 XML 实例的某些部分,例如添加或删除子树,或者更新标量值(如将书的价格从 9.99 替换为 39.99)。例:使用 query() 方法考虑下面的表 docs 的 XML 列 xCol 中的查询,它提取 元素下的任何位置的 id 为 123 的 元素。该查询也从整型主键列检索值。SELECT 列表中的 query() 方法会为生成

35、 元素序列的表中的每一行进行求值, 元素及其子树是按照文档顺序进行检索的。对于每个 XML 实例,如果没有 id 为 123 的 元素或者其下没有 元素,则不会返回结果,也就是说,query() 方法的返回值为 NULL。 SELECT pk, xCol.query('/docid = 123/section') FROM docsNULL 返回值可以在外部 SELECT 语句中过滤掉。或者也可以使用 exist() 方法,如下一个示例所示。例:使用 exist() 方法考虑下面的查询,它在表 docs 的 XML 列 xCol 中包括 query() 和 exist() 方法

36、。exist() 方法求路径表达式 /docid = 123 的值,检查是否存在顶层 元素,该元素具有一个称为 id 的属性,且其值为 123。对于每个这样的行,SELECT 子句中的 query() 方法都会进行求值;在这个示例中,query() 方法在 元素下的任何位置都产生一个 元素序列。从 exist() 方法返回 0 的任何行都会被忽略。SELECT xCol.query('/docid = 123/section') FROM docs WHERE xCol.exist ('/docid = 123') = 1例:使用 value() 方法下面的查询

37、使用 value() 方法以 Unicode 字符串的形式提取文档第三部分的标题。结果的 SQL 类型的 nvarchar(max) 被指定为 value() 方法的第二个参数。XQuery 函数 data() 从 节点提取标量值。SELECT xCol.value( 'data(/doc/sectionnum = 3/heading)1)', 'nvarchar(max)') FROM docsXQuery 语言众多的 XML 都来源于存储在文件系统、Web 服务或配置文件中的 Office 文档。事实上,以 XML 格式或作为虚拟 XML 文档生成的数据正在

38、不断地增加。为了处理这些数量越来越多的数据,一种强大的查询语言 XQuery 应运而生。在 XQuery 语言规范(位于 /TR/xquery)中将选择 XQuery 的理由描述为: · 一种巧妙地使用 XML 结构的查询语言,可以跨各种数据表示查询,而不管这些数据是物理存储在 XML 中,还是通过中间件被视为 XML。该规范描述了一种称为 XQuery 的查询语言,它旨在能广泛应用于许多类型的 XML 数据源。 · XQuery 旨在满足 W3C XML 查询工作组 XML 查询 1.0 要求和 XML 查询用例中的用例所确定的要求。它是一

39、种旨在使查询简洁易懂的语言。它还相当地灵活,可以查询大范围的 XML 信息源,其中包括数据库和文档。 · XQuery 还可以概括为如下表述:XQuery 语言之于 XML 正如 SQL 语言之于关系数据库。内嵌于 T-SQL 的 Xquery 子集(位于 /TR/xquery/)是一种支持查询 XML 数据类型的语言。这种语言正在由 Worldwide Web Consortium (W3C) 进行开发(目前处于最后请求状态),所有主要的数据库厂商(包括 Microsoft 在内)都参与其中。我们的实现与 2003 年 11 月发布的 XQuery

40、草案是一致的。XQuery 将 XPath 2.0 作为导航语言包括在内。SQL Server 2005 的 XQuery 实现提供了用于遍历节点 (for)、节点检查 (where)、返回值 (return) 和排序 (order by) 的构造。它也提供了用于在查询过程中重新进行数据构形的元素构造。SQL Server 2005 还提供了用于 XML 数据类型的数据修改 (DML) 的语言构造(请参阅下面的“数据修改”一节以获得更多信息)。下面的示例演示了如何将 XQuery 用于 XML 数据类型。例:使用 XQuery 中丰富的语言构造下面的查询显示了如何一起使用几个 XQuery 语

41、言构造。它从 id 为 123 的文档返回区域号为 3 和更高的区域中的标题,并将其包装在新标记 中。 SELECT pk, xCol.query(' for $s in /docid = 123/section where $s/num >= 3 return <topic>data($s/heading)</topic>') FROM docs“for”遍历 id 为 123 的<doc> 元素下的所有<section> 元素,并且将每个这样的<section> 元素绑定到变量 $s。“where”确保区域号

42、(<section> 元素的 num 属性)为 3 或更高。该查询按照文档顺序返回区域<heading> 中的值,并且将其包装在一个称为<topic> 的构造元素中。查询编译和执行SQL 语句是由 SQL 解析器解析的。当它遇到 XQuery 表达式时,它就会跳转到 XQuery 编译器,然后编译 XQuery 表达式。这会产生一个查询树,并将其嫁接到整个查询的查询树上。 整个查询树会进行查询优化并产生物理查询计划,该计划是根据基于成本的评估得出的。Showplan 输出显示了大部分关系运算符和一些新的运算符(例如,用于 XML 处理的 UDX)。 查询执行

43、与关系框架中的其余部分一样,都是面向元组的。在表 docs 的每一行上都求 WHERE 子句的值;这需要在运行时解析 XML BLOB 以求出 XML 数据类型方法的值。如果条件满足,则锁定行,然后在行中求 SELECT 子句的值。结果以 XML 数据类型的形式产生(用于 query() 方法),并且转换成指定的目标类型(用于 value() 方法)。 而如果该行不满足 WHERE 子句中的条件,它就会被忽略,执行转到下一行。XML 数据修改SQL Server 2005 提供了用于数据修改的构造作为对 XQuery 的一个扩展。子树可以在指定的节点之前或之后插入,或者作为最左边或最右边的子节

44、点插入。此外,子树也可以插入到父节点,在这种情况下,它成为父节点最右边的子节点。属性、元素和文本节点插入都支持。支持删除子树。在这种情况下,整个子树就从 XML 实例中被移除。 标量值可以用新的标量值进行替换。 例:将子树插入 XML 实例这个示例显示了 modify() 方法的使用,它将一个新的<section> 元素插入编号为 1 的 元素的右边。UPDATE docs SET xCol.modify(' insert <section num="2"> <heading>Background</heading>

45、</section> after (/doc/sectionnum=1)1')例:将这本书的价格更新为 $49.99下面的更新语句将 ISBN 为 1-8610-0311-0 的书的<price> 替换为 $49.99。该 XML 实例是通过 XML 架构 http:/myBooksinstance 进行类型化的,因而就有了 XML 数据修改语句中的命名空间声明。UPDATE XmlCatalog SET Document.modify (' default namespace = "http:/myBooks" replace va

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

47、y 运行时错误被转换成空序列。 如果编译器不能确定在运行时是否保证有 singleton 元素,则需要 singleton 元素的定位步骤、函数参数和运算符(例如,eq)就会返回错误。这种问题常常因非类型化的数据而产生。例如,查找属性需要 singleton 父元素;顺序选择单个的父节点就足够了。 例:value() 方法中的类型检查下面的查询是在非类型化的 XML 列中进行的,它需要 /author/last-name 中的顺序规范,因为 value() 方法需要 singleton 节点作为第一个参数。如果没有,则编译器就不能确定在运行时是否只出现一个<last-name> 节

48、点。SELECT xCol.value('(/author/last-name)1', 'nvarchar(50)') LastName FROM docs通过求 node()-value() 组合的值来提取属性值可以不需要顺序规范,如下一个示例所示。例:已知的 singleton 元素如下所示的 nodes() 方法为每个<book> 元素生成单独的行。对<book> 节点求值的 value() 方法提取 genre 的值,genre 作为一个属性,是 singleton 元素。 SELECT nref.value('genre

49、', 'varchar(max)') LastName FROM docs CROSS APPLY xCol.nodes('/book') AS R(nref)跨域查询如果数据驻留在关系数据类型的列和 XML 数据类型的列的组合中,就可能需要编写查询来组合关系数据处理和 XML 数据处理。通过使用带有 TYPE 指令的 FOR XML,可以将关系列和 XML 列中的数据转换成 XML 数据类型的实例,并使用 XQuery 对其进行查询。相反地,可以从 XML 值生成行集,并且使用 T-SQL 来对其进行查询,如下面的“从 XML 数据生成行集”一节所示。

50、编写跨域查询的一个更加方便和有效的方法是,使用 SQL 变量的值,或者使用 XQuery 或 XML 数据修改表达式中的列: · 使用 sql:variable(),可以在 XQuery 或 XML DML 表达式中应用 SQL 变量的值。 · 通过 sql:column(),可以在 XQuery 或 XML DML 上下文中使用来自关系列的值。 这种方法允许应用程序参数化查询,如下面的示例所示。Sql:column() 的用法与前者类似,并且还带来其他的好处。正如基于成本的查询优化器所确定的,可以使用列的索引来提高效率。此外,也可以使用计算列。 XML 和用户定义的类型不

51、允许与 sql:variable() 和 sql:column() 一起使用。例:使用 sql:variable() 的跨域查询在这种查询中,<book> 元素的 ISBN 是使用 SQL 变量 isbn 来传入的。代替使用常量,sql:variable() 提供 ISBN 的值,并且该查询可以用于搜索任何 ISBN,而不只是 ISBN 为 0-7356-1588-2 的 元素。DECLARE isbn varchar(20) SET isbn = '0-7356-1588-2' SELECT xCol FROM docs WHERE xCol.exist (

52、9;/bookISBN = sql:variable("isbn")') = 1从 XML 数据生成行集在自定义属性管理和数据交换场景中,应用程序通常将 XML 数据的某些部分映射到行集。例如,为了将输入参数表传送到存储过程或函数,应用程序需要将数据转换成 XML,并且将其作为 XML 数据类型的参数传入。在存储过程或函数中,行集是从 XML 参数生成的。 SQL Server 2000 为此提供了 OpenXml()。它简化了从 XML 实例生成行集的过程,方法是指定行集的关系架构以及将 XML 实例内的值映射到行集中的列的方式。 另外,还可以使用 nodes()

53、 方法来生成 XML 实例中的节点上下文,并且在 value()、query()、exist() 和 nodes() 方法中使用该节点上下文来生成所期望的行集。nodes() 方法接受 XQuery 表达式,在 XML 列的每个 XML 实例中对其进行求值,并且有效地使用 XML 索引。下一个示例演示如何将 nodes() 方法用于行集生成。 例:从 XML 实例提取属性假定要提取名字不是“David”的作者的名和姓,将其作为由两列(FirstName 和 LastName)组成的一个行集。通过使用 nodes() 和 value() 方法,您可以达到此目的,如下所示:SELECT nref.

54、value('first-name1', 'nvarchar(50)') FirstName, nref.value('last-name1', 'nvarchar(50)') LastName FROM docs CROSS APPLY xCol.nodes('/author') AS R(nref) WHERE nref.exist('.first-name != "David"') = 1在这个示例中,nodes('/author') 产生一个指向每个 XM

55、L 实例的 元素的引用的行集。作者的名和姓是通过对与这些引用有关的 value() 方法求值来获得的。要获得好的性能,需要建立 XML 列的索引,这是下一部分的主题。建立 XML 数据的索引XML 数据是以内部二进制形式存储的,存储容量可以达到 2 GB。每个查询在运行时一次或多次地解析表中每一行的 XML BLOB。这会使查询处理的速度变得很慢。如果在工作负荷中常常需要进行查询,则建立 XML 列的索引是有好处的,不过,这样做必须考虑在修改数据的过程中维护 XML 索引的成本。XML 索引是通过一个新的 DDL 语句在类型化和非类型化的 XML 列中创建的。这为该列中的所有 XML 实例创建

56、了一个 B+ 树。XML 列中的第一个索引是“主 XML 索引”。通过这个索引,可以在 XML 列中支持三种类型的次 XML 索引来加速普通类的查询,如下一节所述。主 XML 索引在基表(即定义 XML 列的表)的主键中,主 XML 索引需要聚集索引。它在 XML 节点的信息集项的一个子集中创建一个 B+ 树。B+ 树的列表示标记,例如元素和属性名称、节点值和节点类型。其他的列捕获 XML 数据中的文档顺序和结构,以及从 XML 实例的根节点到每个节点的路径,从而有效地对路径表达式进行求值。基表的主键在主 XML 索引中复制,以使索引行与基表行相关。 XML 架构中给定的标记和类型名称被映射为

57、整数值,而映射值存储在 B+ 树中以优化存储。索引中的路径列按照相反的顺序(即从节点到 XML 实例的根)存储映射值的串联。当路径后缀已知时(在一个路径表达式中,如 /author/last-name),相反的表示使得可以匹配路径值。 如果对基表进行分区,则需要以相同的方式对主 XML 索引进行分区,也就是使用相同的分区函数和分区架构。全部的 XML 实例都是从 XML 列检索的(SELECT * FROM docs 或 SELECT xCol FROM docs)。需要 XML 数据类型方法的查询使用主 XML 索引,从索引本身返回标量值或 XML 子树。例:创建主 XML 索引下面的语句在

58、表 docs 的 XML 列 xCol 中创建一个名为 idx_xCol 的 XML 索引。CREATE PRIMARY XML INDEX idx_xCol on docs (xCol)次 XML 索引一旦主 XML 索引创建完毕,就可以创建次 XML 索引来加速工作负荷中不同类的查询。三种类型的次 XML 索引 PATH、PROPERTY 和 VALUE 分别对基于路径的查询、自定义属性管理方案和基于值的查询有利。 · PATH 索引在主 XML 索引的列 (path, value) 中构建 B+ 树。该路径的值是通过计算路径表达式和节点的值得出的,如果提供了一个路径值,则也可以

59、使用所提供的值。在已知 PATH 索引开始字段的情况下,查找 PATH 索引可以加速路径表达式的求值。最常见的情况是在 SELECT 语句的 WHERE 子句中对 XML 列使用 exist() 方法。 · PROPERTY 索引在主 XML 索引的列 (PK, path, value) 中创建 B+ 树,其中 PK 是基表的主键。此索引对 XML 实例中的属性值查找有利。 · 最后,VALUE 索引在主 XML 索引的列 (value, path) 中创建一个 B+ 树。此索引对节点的值已知但是其路径没有准确地在查询中指定的查询有利。这通常出现在祖先或自身 (descen

60、dant-or-self) 轴查询中,例如,/authorlast-name="Howard",其中, 元素可以出现在层次的任何一层。它还可以出现在“wildcard”查询中,例如 /book * = "novel",其中,查询查找具有“novel”属性值的 元素。此外,VALUE 索引还可用于对类型化的 XML 进行基于值的范围扫描。 可以容纳多达 128 层的 XML 层次;在插入和修改的过程中,如果 XML 实例包含更长的路径,则会被拒绝。 类似地,可以建立一个节点值的前 128 个字节的索引;系统中可以容纳更长的值,但是不会建立索引。例:基于路径

61、的查找假定下面的查询在工作负荷中是常见的:SELECT xCol FROM docs WHERE xCol.exist ('/bookgenre = "novel"') = 1路径表达式 /book/genre 和值“novel”对应于 PATH 索引的键字段。因此,类型 PATH 的次 XML 索引有助于此工作负荷:CREATE XML INDEX idx_xCol_Path on docs (xCol) USING XML INDEX idx_xCol FOR PATH例:获取对象的属性考虑下面的查询,它从表 T 的每一行检索书的“genre”、“tit

62、le”和 ISBN 属性:SELECT xCol.value ('(/book/genre)1', 'varchar(50)'), xCol.value ('(/book/title)1', 'varchar(50)'), xCol.value ('(/book/ISBN)1', 'varchar(50)') FROM docs属性索引可用于这种情况,该索引创建如下:CREATE XML INDEX idx_xCol_Property on docs (xCol) USING XML INDEX i

63、dx_xCol FOR PROPERTY例:基于值的查询在下面的查询中,祖先或自己轴 (/) 指定了部分路径,这样,基于 ISBN 值的查询就可以从 VALUE 索引的使用中受益:SELECT xCol FROM docs WHERE xCol.exist ('/bookISBN = "1-8610-0157-6"') = 1VALUE 索引创建如下:CREATE XML INDEX idx_xCol_Value on docs (xCol) USING XML INDEX idx_xCol FOR VALUE内容索引可以在 XML 列中创建全文本索引;这会

64、建立 XML 值内容的索引而忽略 XML 标记。属性值不是全文本索引的(因为它们被认为是标记的一部分),而元素标记被用作标记边界。可以在 XML 列中创建 XML 和全文本索引,并且组合使用全文本搜索和 XML 索引。使用全文本索引作为第一个筛选器来缩小选择范围,接着再应用 XQuery 进一步筛选。使用 CONTAINS() 和 XQuery contains() 的全文本搜索有不同的语义。后者是子字符串匹配,而前者是使用词根检索的标记匹配。 例:在 XML 列中创建全文本索引在 XML 列中创建全文本索引的步骤与在其他 SQL 类型列中创建全文本索引的步骤是非常相似的。需要在基表中有一个唯一的键列。DDL 语句如下,其中,PK_docs_7F60ED59 是该表的单列主键索引:CREATE FULLTEXT CATALOG ft AS DEFAULT CREATE FULLTEXT INDEX ON dbo.docs (xCol) KEY INDEX PK_docs_7F60ED59例:组合全文搜索和 XML 查询下面的查询检查 XML 值是否在书的标题中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论