从 SQL Server 2005 中处理 XML(1)


一、简介

Microsoft SQL Server 2005 中的重大更改之一是包含了 XML 数据类型。此数据类型是第一类类型,就像 INTVARCHAR 一样,而且 SQL Server 2005 允许使用一系列 XML 特定的函数对此数据类型进行就地查询和处理。它还支持存储数据库中的 XML 架构的集合,从而启用基于数据库的架构验证。另外,SQL Server 2005 大大地扩展了 XML 组合(SELECT ... FOR XML 语句)的功能,扩展了 OpenXML() XML 分解函数,并针对 XML 数据类型提供了一个新的 nodes() 函数以进行更轻量级的分解。

既然对数据库服务器增强了此新的 XML 功能,那么对 Microsoft ADO.NET 2.0 中的 SqlClient 数据提供程序也进行增强就不会令人感到惊奇了。对 ADO.NET DataSet 也有更改,以便支持类型 XMLDataColumn ,而且 System.DataSystem.Xml 之间的“集成点”得到了拓宽。在本文中,我将探究在客户端上使用 SQL Server 2005 XML 数据类型。

SQL Server 2005 可以产生两类 XML 输出。语句 SELECT * FROM AUTHORS FOR XML AUTO 产生 XML 流,而不是一列一行的行集。该输出类型与 SQL Server 2000 中的输出类型相比没有改变。只是因为查询分析器工具中的限制,XML 流输出在 SQL Server 查询分析器中才显示为一列一行的行集。您可以通过其特定的唯一标识符名称“XML_F52E2B61-18A1-11d1-B105-000805F49916B”来将这种流与“普通”列区分开来。此名称实际上是底层 TDS(这是一种表格式的数据流,SQL Server 网络格式)分析器的指示器,在这种分析器中,列应该流至客户端,而不是像普通行集那样发送。有一种特殊的方法 SqlCommand.ExecuteXmlReader 用来在客户端上检索此特殊的流。在 SQL Server 2005 中,SELECT ... FOR XML 语句通过许多方式得到了增强。这里仅提少数几种:

1.

|

在大多数情况下,当您需要 SQL Server 2000 中的 FOR XML EXPLICIT 模式时,有一种新的、便于使用的 FOR XML PATH 模式。

---|---

2.

|

使用 TYPE 指令,除了生成流之外,您还可以生成 XML 数据类型列。

3.

|

可以嵌套 FOR XML 表达式。

4.

|

SELECT ... FOR XML 可以使用 ROOT 指令生成 XML 文档以及 XML 片段。

5.

|

您可以将标准的 XSD 架构预先挂起到流。

通过引用 ADO.NET 2.0 中的关系 datatype 枚举,您可以初步了解到 XML 是一种一流的关系数据库类型。 System.Data.DbTypeSystem.Data.SqlDbType 分别包含 DbType.XmlSqlDbType.Xml 的附加值。在 System.Data.SqlTypes 命名空间中也有一个新的类,它是 SqlXml 。这个类充当 XML 类型值的 XmlReader 实例工厂。我将通过一些简单的代码进行展示。假设我有一份 SQL Server 表,如下所示:

CREATE TABLE xmltab (
  id INT IDENTITY PRIMARY KEY,
  xmlcol XML)

我可以使用以下 ADO.NET 2.0 代码在客户端上访问此表。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Xml;

void GetXMLColumn {
// "Generic Coding..." article for shows how to
// get a connection string from a config file
string s = GetConnectStringFromConfigFile("xmldb");
using (SqlConnection conn = new SqlConnection(s))
using (SqlCommand cmd = new SqlCommand(
       "select * from xmltab", conn))
 {
  conn.Open();
  SqlDataReader rdr = cmd.ExecuteReader();
  DataTable t = rdr.GetSchemaTable();

  while (rdr.Read())
    {
      SqlXml sx = rdr.GetSqlXml(1);
      XmlReader xr = sx.CreateReader();
      xr.Read(); 
      Console.WriteLine(xr.ReadOuterXml());
    }
 }
}

我浏览 GetSchemaTable 产生的 DataTable 时返回的列元数据正确地标识了列:

ProviderType: 25 (25 = XML)
ProviderSpecificDataType: System.Data.SqlTypes.SqlXml
DataType: System.Xml.XmlReader
DataTypeName:

正如任何其他构建到 SQL Server 中的类型一样。请注意,此列的“.NET 类型”是 XmlReader ,对于 .NET 而言,它就像任何从文件加载或用 XmlDocument 类产生的 XML 一样。在 ADO.NET 2.0 中的存储过程或参数化语句中将 XML 数据类型列用作参数同样简单:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Xml;

void AddARow {
// get a connection string from a config file
string s = GetConnectStringFromConfigFile("xmldb");
using (SqlConnection conn = new SqlConnection(s))
using (SqlCommand cmd = new SqlCommand(
       "insert xmltab(xmlcol) VALUES(@x)", conn))
 {
  conn.Open();
  cmd.Parameters.Add("@x", SqlDbType.Xml);

  // connect the parameter value to a file
  XmlReader xr = XmlReader.Create("somexml.xml");
  cmd.Parameters[0].Value = new SqlXml(xr);
  int i = cmd.ExecuteNonQuery();
 }
}
Published At
Categories with 数据库类
Tagged with
comments powered by Disqus