如何使用SQL Server 2000中的XML功能(1)

<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>

SQL Server 2000提供了一些XML功能,用于通过XML将关系行集合转换成分层的XML文档、读取XML文档和批量加载数据。例如,可以将XML文档传递到存储过程,将XML联接到某些表并返回一个行集合,甚至可以在数据库中修改数据。XML在当今企业系统中不断扩展的功能促进了OPENXML函数和FOR XML语句的引入。其中某些功能不但支持XML,而且还提高批量加载数据时的性能。

在本文中我们将讨论如何通过T-SQL的FOR XML子句从SQL Server返回XML。本文将通过几个例子来介绍返回XML数据和架构信息的几种不同方式,还将介绍将XML转换成更令人满意的格式的方法。然后讨论OPENXML,以及将XML文档联接到数据库表和使用WriteXML和GetXML方法从数据集提取XML的方法。这些例子的SQL,以及执行其中某些例子并将它们导出为文本文件的示例ASP.NET 项目,都可从MSDN Magazine Web站点下载。该示例项目中还包含了用于从XML将记录插入和更新到数据库的代码。

返回XML

当用于SELECT语句中时,FOR XML子句指示SQL Server将数据作为XML返回,这与标准行集合相反。可以指定返回模式:RAW、AUTO或EXPLICIT。每种模式都提供了XML的不同转换方式(图 1 给出了各种模式的概述)。



图 1 FOR XML模式概述

模式 说明 RAW                            行集合的每个记录都转换成叫做行的XML元素。<row>元素将包含一个属性,用来表示所检索的列。 AUTO 行集合记录可以转换成以FROM子句中的表命名的嵌套XML元素。所检索每一列都将表示为一个属性 EXPLICIT 为格式化XML提供许多控制。不过,EXPLICIT模式的使用语法要复杂得多。XSLT是一个比较常用的XML转换方法。

例如,若使用FOR XML RAW来查询Northwind数据库的Employees表,它会在<row>元素中返回每个员工行。SELECT语句中包含的每一列都会表示为<row>元素的一个属性。下面的FOR XML RAW查询选择两个员工记录,然后以RAW格式返回:   

SELECT EmployeeID,

FirstName, LastName

FROM Employees

WHERE LastName LIKE 'D%'

FOR XML RAW

<row EmployeeID="1" FirstName="Nancy" LastName="Davolio"/>

<row EmployeeID="9" FirstName="Anne" LastName="Dodsworth"/>

对该SELECT语句作一下修改就可以使用FOR XML AUTO子句。这次将元素命名为Employees,与源表的名称匹配。列仍是主元素的属性:  

SELECT EmployeeID, FirstName, LastName

FROM Employees

WHERE LastName LIKE 'D%'

FOR XML AUTO

<Employees EmployeeID="1" FirstName="Nancy" LastName="Davolio"/>

<Employees EmployeeID="9" FirstName="Anne" LastName="Dodsworth"/>

转换和层次结构

 

尽管上例中的区别较小,但与用于联接表的一个查询一起使用时,AUTO和RAW之间的区别比较明显。无论数据是来自一个表还是来自多个表,使用FOR XML RAW的查询都将只返回<row>元素。因此,RAW模式不利用XML文档的固有分层结构。请看下面的SQL语句:

SELECT   Customers.CustomerID,

CompanyName,

OrderID,

CONVERT(VARCHAR(10), OrderDate, 101) AS OrderDate

FROM     Customers

INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID

ORDER BY Customers.CustomerID

本例将检索一种一对多父子关系。若执行该SQL语句,则将返回一系列客户及其相应定单。若附带FOR XML RAW子句并再次执行,则得出的XML结果将包含一个表示所返回的每一行的单<row>元素。例如,图 2中的XML数据表示CustomerID为ALFKI时FOR XML RAW将返回的行。

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="10643"

OrderDate="08/25/1997" />

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="10692"

OrderDate="10/03/1997" />

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="10702"

OrderDate="10/13/1997" />

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="10835"

OrderDate="01/15/1998" />

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="10952"

OrderDate="03/16/1998" />

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" OrderID="11011"

OrderDate="04/09/1998" />

图 2  XML数据

请注意,这些数据不以父子层次结构显示。若想让数据显示为包含一系列相关<Orders>元素的一系列<Customers>元素,则可使用FOR XML AUTO子句(父子嵌套方法取决于成组聚集的父行)。CustomerID为ALFKI 时的XML结果如下:

<Customers CustomerID="ALFKI" CompanyName="Alfreds Futterkiste">

<Orders OrderID="10643" OrderDate="08/25/1997" />

<Orders OrderID="10692" OrderDate="10/03/1997" />

<Orders OrderID="10702" OrderDate="10/13/1997" />

<Orders OrderID="10835" OrderDate="01/15/1998" />

<Orders OrderID="10952" OrderDate="03/16/1998" />

<Orders OrderID="11011" OrderDate="04/09/1998" />

</Customers>

XML的可读性大大提高,因为它使用表名来作为元素名。它所包含的数据也比较少,因为它不重复每个定单元素的CustomerID和CompanyName属性,而FOR XML RAW例子则不然。

如果您更喜欢将列值表示为元素而不是属性,则您就会很幸运。通过在FOR XML子句中指定ELEMENTS选项,所有列值都将成为XML中的元素。有时百闻不如一见,因此本文在图 3中给出了当ELEMENTS条件适用时前面查询的输出。(为了简便起见,给出的XML示例仅包含CustomerID ALFKI的XML。这些查询所生成的实际XML会包含所有客户及其定单的XML。)使用ELEMENTS选项的查询如下:

SELECT   Customers.CustomerID,

CompanyName,

OrderID,

CONVERT(VARCHAR(10), OrderDate, 101) AS OrderDate

FROM     Customers

INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID

ORDER BY Customers.CustomerID

FOR XML AUTO, ELEMENTS

<Customers>

<CustomerID>ALFKI</CustomerID>

<CompanyName>Alfreds Futterkiste</CompanyName>

<Orders>

<OrderID>10643</OrderID>

<OrderDate>08/25/1997</OrderDate>

</Orders>

<Orders>

<OrderID>10692</OrderID>

<OrderDate>10/03/1997</OrderDate>

</Orders>

<Orders>

<OrderID>10702</OrderID>

<OrderDate>10/13/1997</OrderDate>

</Orders>

<Orders>

<OrderID>10835</OrderID>

<OrderDate>01/15/1998</OrderDate>

</Orders>

<Orders>

<OrderID>10952</OrderID>

<OrderDate>03/16/1998</OrderDate>

</Orders>

<Orders>

<OrderID>11011</OrderID>

<OrderDate>04/09/1998</OrderDate>

</Orders>

</Customers>

图 3 使用FOR XML AUTO, ELEMENTS

XML的可读性大大提高,因为它使用表名来作为元素名。它所包含的数据也比较少,因为它不重复每个定单元素的CustomerID和CompanyName属性,而FOR XML RAW例子则不然。    如果您更喜欢将列值表示为元素而不是属性,则您就会很幸运。通过在FOR XML子句中指定ELEMENTS选项,所有列值都将成为XML中的元素。有时百闻不如一见,因此本文在图 3中给出了当ELEMENTS条件适用时前面查询的输出。(为了简便起见,给出的XML示例仅包含CustomerID ALFKI的XML。这些查询所生成的实际XML会包含所有客户及其定单的XML。)使用ELEMENTS选项的查询如下:

XML的可读性大大提高,因为它使用表名来作为元素名。它所包含的数据也比较少,因为它不重复每个定单元素的CustomerID和CompanyName属性,而FOR XML RAW例子则不然。    如果您更喜欢将列值表示为元素而不是属性,则您就会很幸运。通过在FOR XML子句中指定ELEMENTS选项,所有列值都将成为XML中的元素。有时百闻不如一见,因此本文在图 3中给出了当ELEMENTS条件适用时前面查询的输出。(为了简便起见,给出的XML示例仅包含CustomerID ALFKI的XML。这些查询所生成的实际XML会包含所有客户及其定单的XML。)使用ELEMENTS选项的查询如下:   

XML的可读性大大提高,因为它使用表名来作为元素名。它所包含的数据也比较少,因为它不重复每个定单元素的CustomerID和CompanyName属性,而FOR XML RAW例子则不然。     如果您更喜欢将列值表示为元素而不是属性,则您就会很幸运。通过在FOR XML子句中指定ELEMENTS选项,所有列值都将成为XML中的元素。有时百闻不如一见,因此本文在图 3中给出了当ELEMENTS条件适用时前面查询的输出。(为了简便起见,给出的XML示例仅包含CustomerID ALFKI的XML。这些查询所生成的实际XML会包含所有客户及其定单的XML。)使用ELEMENTS选项的查询如下:    <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>
阅读更多
个人分类: 数据库
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭