扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:51DOTNET整理 来源:51dotnet 2007年10月23日
关键字: SQL Server
在本页阅读全文(共2页)
EXPLICIT模式比较复杂,我们将用另外一种方法来表达图1所显示的查询。这种方法使得我们能够完全地控制查询所生成的XML文档。首先我们将介绍如何改用EXPLICIT模式编写图1所显示的查询,然后看看这种方法如何赋予我们远远超过AUTO模式的能力。
下面是图1查询用EXPLICIT模式表达的代码:
【图2 】
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数据 SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
这个查询初看起来有点复杂,其实它只是把不同的数据集(即这里的Store和Sale)分解到了独立的SELECT语句里,然后再用UNION ALL操作符连结成一个查询。
我们之所以要把查询写成上面的形式,是为了让查询结果不仅包含XML文档所描述的数据,而且还包含描述XML文档结构的元数据。上述查询所生成的表称为Universal表,sqlxml.dll生成XML文档时需要这种格式。Universal表对于编写代码的人来说是透明的,但了解这个表还是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以红色表示,黑色表示数据。比较查询和表就可以找出sqlxml.dll生成XML文档所需要的元素。我们来仔细地分析一下它们描述的是什么。
Tag和Parent列是XML文档层次结构方面的信息,我们可以认为图2中的每个SELECT语句代表了一个XML节点,而Tag和Parent列让我们指定节点在文档层次结构中的位置。如果在第二个SELECT语句中指定Tag为2、指定Parent为1,就表示为这些数据加上了一个值为2的标签,而这些数据的父亲是那些标签为1的数据(即第一个SELECT语句)。这就使得我们能够构造出<Store>和<Sale>之间的父-子关系,而且正如你可能猜想到的,它使得我们可以生成任意合法的XML文档结构。注意第一个SELECT命令的parent列设置成了NULL,这表示<Store>元素处于最顶层的位置。
以黑色表示的数据将成为节点的属性或元素,例如,Store_ID就通过列名提供了这方面的信息。列名字中的“!”是分隔符,总共可分成四项(四个参数),其中第四个参数是可选的。这些参数描述的是:
第一个参数描述该列所属元素的名字,在这里是<Store>元素。
第二个是标签编号,它指定了该列信息在XML树形结构中所处位置。
第三个参数指定XML文档内的属性或元素名字。在这里名字指定为id。
数据列默认被创建为参数2所指定节点的属性,即id将成为<Store>节点的属性。如果要指定id是<Store>的一个子元素,我们可以使用第四个可选的参数,这个参数的一个作用就是让我们把该项指定为元素,例如store!1!id!element。
由于使用了UNION ALL操作符来连结SELECT语句,为了保证SQL查询的合法性,所有SELECT语句的选择结果必须具有相同数量的列。我们使用NULL关键词来补足SELECT语句,从而避免了重复数据。
通过EXPLICIT模式查询所生成的XML文档和通过AUTO模式生成的完全相同,那么为什么要创建EXPLICIT模式查询呢?
假设现在有人要求在XML文档中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一种合理的方法是在<Store>元素下面加上子元素<Discount>,这样我们就得到如下XML文档结构:
<STORES> <STORE Id=&single;&single; Name=&single;&single;> <DISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;> <AMOUNT></AMOUNT> </DISCOUNT> <SALE OrdNo=&single;&single; Qty=&single;&single;> </SALE> </STORE> </STORES> |
这里的改动包括:
要在<Sale>元素所在的层次增加一个XML元素<Discount>,即<Discount>是<Stroe>的子元素。
Amount嵌套在<Discount>里面,但不应该是<Discount>元素的属性。
在AUTO模式中是不可能实现这些改动的。
下面是创建这个新XML文档的EXPLICIT模式查询:
【图 2A】
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
为了创建图2A所显示的EXPLICIT模式查询,我们对图2的查询进行了如下修改:
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签值为3。
通过指定Parent列为1将折扣数据设置成<Store>元素的子元素。
注意在第三个SELECT子查询中我们只包含了那些必需的列,并用NULL补足空列。这个子查询包含store_name列,虽然Discount元素并不要用到这个列,但如果把这个列也设置为NULL,则结果Universal表将不会按照解析器所要求的那样以节点升序排序(不妨自己试一下看看)。Universal表的排序列也可以用Tag列替代。
为维持结果Universal表的完整性,第一、二两个SELECT语句也用NULL补足以反映为折扣数据增加的列。
为指定新折扣列的元数据修改了第一个SELECT语句。
通过在第四个参数中声明element指定Amount列为Discount的一个元素(element是可在第四个参数中声明的多个指令之一)。
下面这个XML文档只能用EXPLICIT模式生成:
结果XML文档中不会显示出NULL数据,如折扣lowqty和highqty。
看来上面的介绍,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显示出来,比如可以将数据显示在浏览器上。下面这个例子就使用FOR XML和ADO将数据输出到浏览器的例子。
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘建立ADODB Stream 对象,ADODB Stream 对象需要ADO2.5以上版本支持,它可以将记录集转换为数据流。 Response.write "Pushing XML to client for processing " & "<BR/>" adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOM方法将XML的文本转换为HTML Dim xmlDoc Dim root, child For each child in root.childNodes </SCRIPT> |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者