SQL Server 2000数据库FOR XML查询概述(2)
作者:肯尼思 出处:赛迪网 更新时间:2008-08-07 责任编辑:seward
 
 

三.使用EXPLICIT模式

该模式使用起来相对比较复杂,不过它可以很灵活的控制返回的xml数据结构。在该查询中定义了两个表示元数据的额外列。Tag列唯一的确定用来在结果中表示每一行的xml标记,Parent列用来控制元素之间的嵌套关系。

1.使用通用表

EXPLICIT模式下有一个通用表的概念,使用数据列的名称来定义xml文档中的数据。结构如下:

ElementName!TagNumber!AttributeName!Directive

下面的说明来自联机丛书,

ElementName

是所得到的元素类属标识符(例如,如果将 Customers 指定为ElementName,则 是元素标记)。

TagNumber

是元素的标记号。借助于通用表中的两个元数据列(Tag 和 Parent),TagNumber用于表示 XML 树中的 XML 元素嵌套。每个TagNumber都准确对应于一个ElementName。

AttributeName

是 XML 特性的名称(如果没有指定Directive)或包含的元素名(如果Directive是 xml、cdata 或 element)。如果指定Directive,则AttributeName可以为空。这种情况下,列中包含的值直接由具有指定ElementName的元素所包含。

Directive

是可选命令。如果没有指定Directive,则必须指定AttributeName。如果没有指定AttributeName且没有指定Directive(如 Customer!1),则表示元素命令(如 Customer!1!!element)且包含数据。

Directive有两种用途。该选项用于分别使用关键字 ID、IDREF 和 IDREFS 对 ID、IDREF 和 IDREFS 进行编码。还用于表示如何使用关键字 hide、element、xml、xmltext 和 cdata 将字符串数据映射到 XML。大多数情况下允许在这些组中组合指令,但是不能在组本身中进行组合。

ID

可将元素特性指定为 ID 类型的特性。然后可以使用 IDREF 和 IDREFS 特性引用它们,以启用文档内的链接。但是,如果没有请求 XMLDATA,则此关键字无效。

IDREF

指定为 IDREF 的特性可用于引用 ID 类型的特性,以启用文档内的链接。但是,如果没有请求 XMLDATA,则此关键字无效。

IDREFS

指定为 IDREFS 的特性可用于引用 ID 类型的特性,以启用文档内的链接。但是,如果没有请求 XMLDATA,则此关键字无效。

hide

不显示特性。这对于按照不出现在结果中的特性对结果进行排序可能很有用。

element

不生成特性。而是生成具有指定名称的包含元素(如果没有指定特性名则直接生成包含元素)。包含数据被编码为实体(例如,字符 < 变成 <)。该关键字可以与 ID、IDREF 或 IDREFS 组合。

xml

除了不进行实体编码外,该命令与元素命令相同(例如,字符 < 仍是 <)。除了 hide 外,该命令不能与任何其它命令一起使用。

xmltext

列内容应包在单个标记内,以便与文档的其它部分集成。如果指定了AttributeName,则标记名由指定名称替换;否则通过将内容放在容器的起始处而不进行实体编码,将特性追加到包含元素的当前特性列表。含有该命令的列必须是文本类型(varchar、nvarchar、char、nchar、text、ntext)。该命令只能与 hide 一起使用。在提取存储在列中的溢出数据时该命令很有用。 如果内容不是有效的 XML,则该行为不明确。

cdata

通过用 CDATA 节环绕数据来包含数据。不对内容进行实体编码。原始数据类型必须是文本类型(varchar、nvarchar、text、ntext)。该命令只能与 hide 一起使用。当使用该命令时,不应指定AttributeName。

2.简单查询

在指定数据所在的元素的名称和标记时必须使用ElementName参数和Tag参数,也就是查询语句中表中存在的每一个实际的数据列都必须以ElementName!Tag开头。在没有指定AttributeName!Directive的情况下以元素值的形式返回。在只查询一个表的情况下Tag为1,Parent为NULL。

使用EXPLICIT模式来查询数据我认为使用倒推的方式会比较方便一些,比如我要得到如下结构,

Description

查询语句:

SELECT 1 AS Tag,NULL AS Parent,

CategoryID AS [Category!1!ID],

CategoryName AS [Category!1!Name],

Description AS [Category!1]

FROM Categories

WHERE categoryID > 6 FOR XML EXPLICIT

返回结果:

Dried fruit and bean curd

Seaweed and fish

当然下面的语句同上面的等效,

SELECT 1 Tag,NULL Parent,

CategoryID [Category!1!ID],

CategoryName [Category!1!Name],

Description [Category!1]

FROM Categories

WHERE categoryID > 6 FOR XML EXPLICIT

2.连接查询

在EXPLICIT模式下的多表连接查询可能相对比较复杂些,先来看一个简单的例子,

查询语句:

SELECT 1 AS Tag,NULL AS Parent,

Categories.CategoryID AS [Category!1!ID],

Categories.CategoryName AS [Category!1!!element],

ProductID AS [Category!1!ProductID!element],

ProductName AS [Category!1!ProductName!element]

FROM Categories

JOIN Products ON Categories.CategoryID = Products.CategoryID AND ProductID <5

WHERE Categories.CategoryID < 3 FOR XML EXPLICIT

返回结果:

Beverages

1

Chai

 

Beverages

2

Chang

 

Condiments

3

Aniseed Syrup

 

Condiments

4

Chef Anton&apos;s Cajun Seasoning

 

 

从上面的结构可以看出数据的xml结构不是很舒服,存在比较大的冗余。想象中改进后的结构如下:

3

Aniseed Syrup

 

4

Chef Anton&apos;s Cajun Seasoning

 

 

1

Chai

 

2

Chang

 

 

从上面看出Category元素的Tag为1,Parent为NULL,而Product元素的Tag为2,Parent为1(即Category的Tag值)。这里有一个问题需要解决,那就是在Tag和Parent中存在两套值,这里就需要使用UNION ALL运算符来实现这项功能,UNION ALL运算符的一项功能就是消除查询返回的重复的行。使用UNION ALL时需要注意的是结果集的列数必须相同。

查询语句:

SELECT 1 AS Tag,NULL AS Parent,

CategoryID AS [Category!1!ID],

CategoryName AS [Category!1!Name],

NULL AS [Product!2!ProductID!element],

NULL AS [Product!2!ProductName!element]

FROM Categories WHERE CategoryID < 3

UNION ALL

SELECT 2 AS Tag,1 AS Parent,

Categories.CategoryID AS [Category!1!ID],

Categories.CategoryName AS [Category!1!Name],--这里可以使用NULL代替

ProductID AS [Product!2!ProductID!element],

ProductName AS [Product!2!ProductName!element]

FROM Categories

JOIN Products ON Categories.CategoryID = Products.CategoryID AND ProductID <5

WHERE Categories.CategoryID < 3

ORDER BY [Category!1!ID] DESC,[Product!2!ProductID!element] ASC

FOR XML EXPLICIT

返回结果:

3

Aniseed Syrup

 

4

Chef Anton&apos;s Cajun Seasoning

 

 

1

Chai

 

2

Chang

 

 

不带FOR XML EXPLICIT语句的结果为:

Tag Parent Category!1! ID Category!1!Name Product!2! Product!2!

ProductID!element ProductName!element

---- ------- ---------- ------------ -------------------------- ----------------------------

1 NULL 2 Condiments NULL NULL

2 1 2 Condiments 3 Aniseed Syrup

2 1 2 Condiments 4 Chef Anton's Cajun Seasoning

1 NULL 1 Beverages NULL NULL

2 1 1 Beverages 1 Chai

2 1 1 Beverages 2 Chang

 
     
 
 
继续>>SQL Server
[第1页][第2页][下一页]
 
内容导航  
第1页SQL Server 2000数据库.. 第2页SQL Server
上一篇 : SQL Server 2000数据库F.. 下一篇SQL Server 2000数据库F..
 
  您要为所发表的言论的后果负责,请各位遵纪守法并注意文明用语
标题:  

[ 关于本站 ] [ 广告服务 ] [ 商务合作 ] [ 联系我们 ] [ 合作伙伴 ] [ 法律顾问 ] [ 网站地图 ]
千橡公司 京ICP证041489号 Copyright (c) 1997-2007 All Right Reserved.