深入探讨 SQL Server 2000 对XML的支持

  [作者 : Wayne, 新一代程序 ,十二 岁时开 始学 习编 程,十三 岁时拥 有自己的 电脑 ,先后学 Basic Pascal C FOXPRO VB DELPHI C++ SQL ,学 Java 言后,遂成 Java 狂崇拜者, 于中国科技大学。

  引言

  我 可以很 简单 的使用 ADO 访问 数据 中的数据,但是,如果我 想把从数据 索得到的数据以 XML 的格式 示出来的 ,就要 点神了,当然,我 可以去找一些 成的 用程序或者是把 有的存 储过 程修改一下,来完成 个想法。

   虽说 ADO2.5 宣称支持 XML ,但是它仍需要一个 外的 理把数据 化成 XML 程。幸好有了 SQL Server 2000 ,它宣称可以直接从数据 中取出数据,而不通 ADO2.5 直接把数据以 XML 方式 示出来。 个功能极大的提高了构造分布式、数据集中的 用程序的性能,因 为这 个特性消除了不必要的代 码层

   看一看, 了支持 XML SQL Server 2000 添加了什 新的特性:

   1 、能 使用 HTTP 访问 SQL Server

   2 、支持 XDR XML 数据 化)架构并且能 指定 对这 些架构的 XPath 查询

   3 、能 够检 索并写入 XML 数据:

    使用 SELECT 句和 FOR XML 子句 XML 数据。

    使用 OPENXML 行集提供程序写入 XML 数据。

    使用 XPath 查询语 XML 数据。

   4 、增 Microsoft SQL Server 2000 OLE DB 提供程序 (SQLOLEDB) ,使得可以将 XML 文档 命令文本并以流的形式返回 果集。

  可 ,我 可以使用好几 方法使用 SQL Server 2000 访问 XML 格式的数据:第一 ,在 URL 行的 查询 可以直接 访问 SQL Server 2000 生成 XML 文档(也可以 用存 Web 器上的 XML 模版生成 XML 数据文件)。第二 ,可以使用 SELECT 命令和 FOR XML 关键 字,通 过调 用一个存 储过 程或是通 使用 XPath 查询 来取得 XML 数据。 SQL Server 2000 完全支持 XDR XML 数据 化)架构,具有映射 XML 元素和属性到表和字段中的功能。下面,我就探 一下 SQL Server 2000 XML 的支持特性。

  一、配置 SQL Server 2000 IIS

  在本文的 始,我想先 如何配置 SQL Server 2000 IIS SQL Server 2000 许为 IIS 建一个虚 ,用来直接 访问 一个 SQL 数据 中的数据。一旦在一台配置了 IIS 算机上安装了 SQL Server 2000 ,就可以运行 SQL Server IIS 管理 用工具来配置 SQL Server 2000 IIS

  好, 们开 始配置 程吧!

  在 "SQL Server 工具 " 程序 单击 " IIS 中配置 SQL XML 支持 " 这时 就会出 一个与 IIS 管理器相似的界面。展 器, 取默 Web 站点,点右 ,在 出的菜 新建 选项 ,然后 单击 " " 命令。新虚 的属性 示在屏幕上。在 " 新的虚 属性 " 对话 框的 " " 选项 卡上, 入虚 的名称,在本例中, 请输 Northwind 和物理目 路径(例如 C:\Inetpub\Wwwroot\Northwind ,假 C:\Inetpub\Wwwroot 中已 建了 Northwind 子目 , 当然我 也可以使用 浏览 钮选择 。在 安全性 选项 卡上,填入有效的 SQL Server 信息,在 入下一个 选项 ,它将要求你确 认刚 入的密 。在 数据源 选项 卡上,在 “SQL Server” 框中 入服 器的名称,在 数据 框中, Northwind 数据 的名称。在 " " 选项 卡上,你可以 选择 URL 查询 模板 查询 XPath” POST” 选项

  在构建一个 用程序 ,你不但要考 到能 够访问 SQL Server 数据 ,要有足 的安全 级别 以保 你的数据的安全性。在 名称 选项 卡上,你可以更具自己的需要 选择 新建模板 型( template) 、架构 (schema) 和模板和架构 型( dbonject ),并 建它 的路径。好,我 们这样 建了虚 Northwind 。默 情况下,使用 录对 Northwind 数据 库执 行指定的 查询 。你一定迫不及待的吸 高看看 SQL 果是什 么样 的了吧?好, 浏览 器中 http://localhost/northwind?sql=SELECT * FROM CUSTOMERS FOR XML AUTO&root=root 试验 一下吧!

  我 们还 可以 程来 实现 配置 SQL Server 2000 IIS 请见 下面的代

  
   Set ObjXML  =  CreateObject( " SQLVDir.SQLVDirControl " )

  ObjXML.Connect 
' Connect to the local computer and Web site "1"

  Set ObjVDirs 
=  ObjXML.SQLVDirs

  Set ObjVDir 
=  ObjVDirs.AddVirtualDirectory( " Northwind " )

  ObjVDir.PhysicalPath 
=   " C:\Inetpub\wwwroot\northwind "

  ObjVDir.UserName 
=   " wayne "   ' SQL Server login

  ObjVDir.Password 
=   ""   ' SQL Server Password

  ObjVDir.DatabaseName 
=   " Northwind "

  objVDir.AllowFlags 
=   73

  Set objVNames 
=  objVDir.VirtualNames

  objVNames.AddVirtualName 
" dbobject " 1 ""

  objVNames.AddVirtualName 
" schema " 2 , " C:\Inetpub\wwwroot\northwind\schema "

  objVNames.AddVirtualName 
" template " 4  ,  " C:\Inetpub\wwwroot\northwind\template "

  objXML.Disconnect

  msgbox 
" Done. "

  二、使用 HTTP SQL

  使用我 们刚 建的虚 ,我 就可以通 SQL 查询语 句写入 URL 的方式 查询 。打 开浏览 器,在地址 中写入以下 URL http://localhost/northwind?sql=SELECT+ *+FROM+Customers+WHERE+CustomerID='ANTON' +FOR+XML+AUTO&root=root ,如果你使用的虚 录别 名不是 Northwind 或者你使用一个 程服 器,只需要把相 改掉就可以了。

   浏览 器中会出

<?xml version = " 1.0 " encoding = "utf - 8 " ?>
<root>
<Customers CustomerID
= "ANTON" CompanyName = "Antonio Moreno Taquería" ContactName = "Antonio Moreno" ContactTitle = "Owner" Address = "Mataderos  2312 " City = "México D.F." PostalCode = " 05023 " Country = "Mexico" Phone = "( 5 555 - 3932 /
/ root>

   来分析一下 URL “http://localhost/northwind” 后面跟了一个 SQL 查询语 句,用来 查询 数据 Northwind 的任 。在本例中,我 使用的 查询语 句是 “SELECT+*+FROM+Customers+WHERE+CustomerID='ANTON'” 注意, 句已 URL 编码过 了,其中的空格都被替 成加号 “+” 这样 它才能被 浏览 器正确的 送到数据 中去, URL 编码 格式 您参 文档。

  在 查询语 句之后,有添加了两个新的 关键 字: FOR XML AUTO FOR XML 关键 字可以 对现 有的 系数据 库执 SQL 查询 ,以返回 XML 文档形式。 AUTO 模式 查询结 果作 嵌套 XML 元素返回,在 FROM 子句内, 个在 SELECT 子句中至少有一列被列出的表都表示 一个 XML 元素, SELECT 子句中列出的列映射到适当的元素特性,当指定了 ELEMENTS 选项 后,表列映射到子元素而非特性。默 情况下, AUTO 模式将表列映射到 XML 特性。

  在 FOR XML AUTO 后, 需要添加一个参数 “root” ,其参数 返回的 XML 文件的 root 元素名。比如 ,你可以把上面我 出的例子中的 root 的参数 值设为 Northwind ,你会 发现 ,返回的 XML 文件中除了 root 元素名 变为 Northwind 了以外,其它都没有 化。

  上面我 们说 的是直接使用 HTTP 简单 查询 ,除此之外你 可以 行更加 复杂 查询 ,比如 说连 接不同的表 查询 看下面的例子,在下例中, SELECT 接了 Northwind 数据 的中的 Customers Orders 表,并返回信息。

http://localhost/northwind?sql=SELECT
Customer.CustomerID%2cCustomer.Contact
Name% 2c %5bOrder%5d.OrderID+FROM+Customers+
Customer+INNER+JOIN+Orders+%5bOrder%
5d+ON+Customer.CustomerID%3d%5bOrder%
5d.CustomerID+FOR+XML+AUTO&root=Northwind

返回的 XML文件太 ,我就不把它列出来了。

  如果你不想在 Customers表和 Orders表中出 嵌套的 SQL Server 2000 提供另一个 关键字用来替代 AUTO关键字就是 RAWRAW 模式将 查询结果集中的 一行 转换为带标识 row XML 元素。 您能 深入了解 RAW ,我再 出一个例子:使用 RAW 模式 索客 订单 信息

  下面的 查询 返回客 订单 信息。在 FOR XML 子句中指定 RAW 模式。


SELECT  Customers.CustomerID, Orders.OrderID, Orders.OrderDate 
FROM  Customers, Orders 
WHERE  Customers.CustomerID  =  Orders.CustomerID 
ORDER   BY  Customers.CustomerID 
FOR  XML  RAW

  下面是部分 果:

row CustomerID="ALFKI" OrderID="10643" OrderDate=" 1997-08-25 T00:00:00"/

row CustomerID="ANATR" OrderID="10308" OrderDate=" 1996-09-18 T00:00:00"/

row CustomerID="ANATR" OrderID="10625" OrderDate=" 1997-08-08 T00:00:00"/

row CustomerID="AROUT" OrderID="10355" OrderDate=" 1996-11-15 T00:00:00"/

  可以使用外部 接指定上面的 查询 果集中返回所有客 ,无 论这 些客 是否有 订单
   
SELECT  C.CustomerID, O.OrderID, O.OrderDate
     
FROM  Customers C  LEFT   OUTER   JOIN  Orders O  ON  C.CustomerID  =  O.CustomerID  ORDER   BY  C.CustomerID  FOR  XML  RAW

  下面是部分 果:


row CustomerID="BONAP" OrderID="11076" OrderDate=" 1998-05-06 T00:00:00"/

row CustomerID="FISSA"/

row CustomerID="PARIS"/

row CustomerID="RICSU" OrderID="11075" OrderDate=" 1998-05-06 T00:00:00"/

  我 们还 可以使用 HTTP 行存 储过 程,比如下面 个名 GetXML 的存 储过 程:
  
CREATE   PROCEDURE  GetXml
   ( 
    
@CustomerID   varchar ( 5 )
   )
   
AS
    
BEGIN
     
SELECT  CustomerID, CompanyName,ContactName
      
FROM  Customers
      
WHERE  CustomerID  LIKE   @CustomerID   +   ' % '
      
FOR  XML AUTO
END

   个存 储过 程并 送相 的参数,我 可以使用下面 URL http://localhost/northwind?sql=exec+GetXml+'A'&root=root 这样 ,我 就能 在更高一 次使用存 储过 程,并且可以根据最 想要得到的 动态 的改 参数 (比如在本例中,我 用的是 “A” )。

  三、使用 XML 模板 查询

   SQL Server 2000 HTTP 求中内嵌 SQL 句的功能 然是非常 大并且有用的。但是 这种见 藏着极大的 患,一旦某个最 了解了直接使用 浏览 查询 数据 的方法,那 数据 中的数据就很危 了,因 可能会 尝试执 行他自己的 insert,update 甚至是 delete 程。

   维护 大部分数据 中数据交易的安全,使用 不能 直接使用 URL 查询 SQL Server 2000 XML 模板的概念,可以 SQL Server URL 查询导 向那些含有所需的 SQL 程的 XML 模板中。

  在我 们讨论 模板概念之前, 重新回到 SQL Server IIS 管理器中, 选项 卡。 了防止用 使用 HTTP 访问 ,我 URL 查询 选项给 去掉。所有 SQL 查询现 在都会被 XML 模板, XPath 中。

   了允 XML 模板 SQL 查询 名称 选项 卡,并 单击 新建按 ,新建一个模板文件 ,取名 templates ,在下拉菜 选择 template 。然后,要 么输 入一个你的 XML 模板将 存的路径或者 单击 浏览 。本例中使用 C:\Inetpub\wwwroot\xml\templates 。一旦你已 提供了所有的必要的信息, 请单击 保存

在一个虚被映射到一个指定来保存 XML查询模板的文件们创建一个有效的 XML模板,用来 SQL查询。下面的代是一个模板示例。
  file2.xml

<Northwind xmlns:sql =
"urn:schemas
- microsoft - com:xml - sql">
<sql:query>
SELECT  Customers.CustomerID, Customers.ContactName, 
Orders.OrderID, Orders.CustomerID
FROM  Customers
INNER   JOIN  Orders
ON  Customers.CustomerID  =  Orders.CustomerID
FOR  XML AUTO
/ sql:query>
/ Northwind>

  段代中使用了一个名sql的前和一个URI urn:schemas-microsoft-com:xml-sql个前用来标识使用在 SQL Server XML ISAPI上的元素。有一个元素名query名思它就是用来标记模板文件中的SQL 查询语句。好,来演示一下如何使用个模板吧!在地址入,http://localhost/northwind/templates/file2.xml,当然你也可以根据你的需要改的服器名和虚名。

   URL拆分成独的片段,行分析,你可以看,我先使用了 northwind根,然后使用templates名,如前我们说过名已映射到templates的物理目中。最后, URL出了模板文件的名称。个模板,浏览器就会把表中customers元素下嵌套的不同的订单XML文档的形式示出来。

  使用模板而不使用 URL查询点。首先,在一个最就没有改SQL句的力了,去除URL查询访问 SQL Server选项 ,就只有SQL Server XML ISAPI可以用来理模板文件,就避免未的 插入、更新和除程序被行。其次, XML模板支持动态加入参数,就允你不用更改模板文件就可以更改一个 SQL WHERE子句的

  使用参数,就像插入一个 XML header元素一样简单的,在 header元素中,定了一个 param元素,使用一个值为CustomerID的名称属性。个参数被予一个默认值"A",你可以象在一个存储过程中一在模板文件中使用个参数,只要在个参数前添加一个@,然后把它放入SQL句或用来用一个存储过程就可以了。请见下面的代

<Northwind xmlns:sql = "urn:schemas - microsoft - com:xml - sql">
<sql:header>
<sql:param name
= ' CustomerID ' >A< / sql:param> 
/ sql:header> 
<sql:query>
SELECT  Customers.CustomerID, Customers.ContactName,
Orders.OrderID, Orders.CustomerID
FROM  Customers
INNER   JOIN  Orders
ON  Customers.CustomerID  =  Orders.CustomerID
WHERE  Customers.CustomerID  LIKE   @CustomerID   +   ' % '
FOR  XML AUTO
/ sql:query>
/ Northwind>

  在本例中,CustomerID参数被一个WHERE子句使用。如果把参数设为"B"SQL 句就会从CustomersOrders表中返回所有的CustomerIDB开头的行。用模板并传递正确的CustomerID参数,只要在查询字符串之后加上参数名和参数,如:http://localhost/northwind/templates/file2.xml?CustomerID=B即可,就这么简单

  四、XPath查询 架构和模板

  XPath查询也可以被内嵌一个XML模板文件中,下面的代是一个包含XPath查询简单XML模板文件。

<Northwind xmlns:sql =
"urn:schemas
- microsoft - com:
xml
- sql">
<sql:xpath
- query mapping - schema =
"file4.xdr">
/ Customer [ @CustomerID=
'ALFKI'
] / Order
/ sql:xpath - query>
/ Northwind>

  查询使用了一个架构(schema)返回CustomerIDALFKI的用的所有的订单,如果想要使XPath句运行,必使用一个XDR架构文件映射不同的XML元素和属性到相的数据表和字段名。下面出了个架构文件。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Customer" sql:relation="Customers">
<AttributeType name="CustomerID" dt:type="id" />
<AttributeType name="CompanyName" />
<AttributeType name="ContactName" />
<AttributeType name="City" />
<AttributeType name="Fax" />
<AttributeType name="Orders" dt:type=
"idrefs" sql:id-prefix="Ord-" />

<attribute type="CustomerID" />
<attribute type="CompanyName" />
<attribute type="ContactName" />
<attribute type="City" />
<attribute type="Fax" />
<attribute type="Orders" sql:relation=
"Orders" sql:field="OrderID">
<sql:relationship 
key-relation="Customers" 
key="CustomerID"
foreign-relation="Orders" 
foreign-key="CustomerID" />
</attribute>

<element type="Order">
<sql:relationship 
key-relation="Customers" 
key="CustomerID"
foreign-relation="Orders" 
foreign-key="CustomerID" />
</element>
</ElementType>

<ElementType name="Order" sql:relation="Orders">
<AttributeType name="OrderID" dt:type=
"id" sql:id-prefix="Ord-" />
<AttributeType name="EmployeeID" />
<AttributeType name="OrderDate" />
<AttributeType name="RequiredDate" />
<AttributeType name="ShippedDate" />

<attribute type="OrderID" />
<attribute type="EmployeeID" />
<attribute type="OrderDate" />
<attribute type="RequiredDate" />
<attribute type="ShippedDate" />

<element type="OrderDetail">
<sql:relationship 
key-relation="Orders" 
key="OrderID"
foreign-relation="[Order Details]" 
foreign-key="OrderID" />
</element>
<element type="Employee">
<sql:relationship 
key-relation="Orders" 
key="EmployeeID"
foreign-relation="Employees" 
foreign-key="EmployeeID" />
</element>
</ElementType>

<ElementType name="OrderDetail" sql:relation=
"[Order Details]"
sql:key-fields="OrderID ProductID">
<AttributeType name="ProductID" dt:type="idref" 
sql:id-prefix="Prod-" />
<AttributeType name="UnitPrice"/>
<AttributeType name="Quantity" />

<attribute type="ProductID" />
<attribute type="UnitPrice"/>
<attribute type="Quantity" />

<element type="Discount" sql:field="Discount"/>
</ElementType>

<ElementType name="Discount" dt:type="string" 
sql:relation="[Order Details]"/>

<ElementType name="Employee" sql:relation="Employees">
<AttributeType name="EmployeeID" dt:type="idref" 
sql:id-prefix="Emp-" />
<AttributeType name="LastName" />
<AttributeType name="FirstName" />
<AttributeType name="Title" />
<attribute type="EmployeeID"/>

<attribute type="LastName" />
<attribute type="FirstName" />
<attribute type="Title" />
</ElementType>
</Schema>

  如果您想深入了解架构文件的参看SQL Server 2000的用文档或等待我的以后的文章。

  和内嵌在XML模板文件中的SQL
查询语句一XPath查询语句使用urn:schemas-microsoft-com:xml-sqlsql,共同示用在模板中的自定元素和属性,XPath查询而言,我使用一个名xpath-query的元素来标识查询语法,个元素也有一个名mapping-schema的属性,用来示相用以映射表和字段到特定的XML目的架构文件所在的路径。

  
下面的代码给出了另一个使用更复杂XPath查询的模板文件。

<Northwind xmlns:sql =
"urn:schemas
- microsoft - com:xml - sql">
<sql:xpath
- query mapping - schema =
"listing4.xdr">
/ Customer [ @CustomerID=
'ALFKI'
] / Order /
Employee
[ @LastName='Suyama' ]
/ sql:xpath - query>
/ Northwind>

  当个模板文件XPath查询返回与某个客户签订单的雇(employee)的姓名,果如下:

<Northwind xmlns:sql =
"urn:schemas
- microsoft - com:xml - sql">
<Employee EmployeeID
= "Emp - 6
LastName
= "Suyama" 
FirstName
= "Michael"
Title
= "Sales
Representative"
/ > 
/ Northwind>

  模板文件中使用的XPath查询也可以使用参数,程很象在XSL式表中使用参数一XSL,使用$指定一个量。下面的代码说明了如何在一个包含XPath查询的模板文件中整合量。

<Northwind xmlns:sql = "urn:schemas - microsoft - com:xml - sql">
<sql:header>
<sql:param name
= "ID" /
/ sql:header>
<sql:xpath
- query mapping - schema = "listing4.xdr"> {{should this be "listing6.xdr"?}}
/ Customer / Order [ @OrderID=$ID ]
/ sql:xpath - query>
/ Northwind>

  通URL传递参数名和相的参数,我就可以完成把参数传递到模板中的操作。果如下:

<Northwind xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Order OrderID="Ord-10643" EmployeeID=
"6" OrderDate="1997-08-25T00:00:00" RequiredDate=
"1997-09-22T00:00:00" ShippedDate=
"1997-09-02T00:00:00">
<Employee EmployeeID="Emp-6" LastName=
"Suyama" FirstName="Michael" Title=
"Sales Representative" /> 
<OrderDetail ProductID="Prod-28" UnitPrice=
"45.6" Quantity="15">
<Discount>0.25</Discount> 
</OrderDetail>
<OrderDetail ProductID="Prod-39" UnitPrice=
"18" Quantity="21">
<Discount>0.25</Discount> 
</OrderDetail>
<OrderDetail ProductID="Prod-46" UnitPrice=
"12" Quantity="2">
<Discount>0.25</Discount> 
</OrderDetail>
</Order>
</Northwind>

  小

  通使用上面我介的几,我可以直接从SQL Server 2000数据中直接取得XML数据。如我所介URL查询XML模板文件、XDR架构和XPath查询提供了大的功能,从SQL Server 2000中直接XML数据。除此之外,有很多重要的概念,由于篇幅有限在本文中不可能述,如FOR XML EXPLICIT查询OPENXML些技,我会在以后的文章中步进讨论大家等待。

你可能感兴趣的:(SQL Server 2000)