.NET 框架 2.0 中的 XQuery
为了在 SQL Server 2005 中补充引入 XQuery,在 Visual Studio 2005 Beta 的 .NET 框架 V2.0 版中,System.Xml.Query 命名空间内置了一个中间层 XQuery 处理器。在这一部分中,我们说明该处理器如何提供查询和聚合完全不同的数据源的能力,例如文件和关系数据存储 SQL Server 数据库。草地chin ai tp owerbEvmRXs
简单的说,下面的代码示例显示了一个查询,用于选择书店中所有 genre 属性值为 autobiography 的书,并且将这些书的标题作为一个新的书店写出。执行查询的称为“books.xml”的本地文件被加载,而将结果写入另一个称为“output.xml”的本地文件。草地chin ai tp owerbEvmRXs
using (XmlWriter writer = XmlWriter.Create("output.xml"))
{
XQueryCommand xq = new XQueryCommand();
string query =
"<bookstore>" +
"{ for $s in /bookstore/book " +
"where $s/@genre='autobiography' " +
"return $s/title }" +
"</bookstore>";
xq.Compile(query);
xq.Execute("books.xml", new XmlUrlResolver(), writer);
}
查询表达式如下:草地chin ai tp owerbEvmRXs
<bookstore>
{for $s in /bookstore/book
where $s/@genre='autobiography'
return $s/title}
</bookstore>
XQueryCommand 类是 XQuery 处理器。首先由 Compile 方法编译查询表达式,该方法对值进行类型检查,并且生成一个可执行文件。Execute 方法执行接受 books.xml 文档作为输入的查询。草地chin ai tp owerbEvmRXs
在 SQL Server(具有将 T-SQL 语句内嵌到 XQuery 表达式的功能)中,XQueryCommand 类还能够对关系表中的数据进行查询。事实上,这使得能够将两个不同的查询语言之间的集成运用于不同的域,并且还补充了反向 SQL Server 2005,其中,T-SQL 语句内嵌到 XQuery 语句。下面的代码示例显示了一个查询,用于从样本 Northwind 数据库中选择所有的顾客。草地chin ai tp owerbEvmRXs
declare namespace sql='http://schemas.microsoft.com/framework/2003/xml/sql';
<Customers>{
$for $customer in sql:query("select * from customers", "conn")/*
return customer
}</Customers>
sql:query 方法使您能够对连接进行 T-SQL 查询,其结果以与 XQuery doc() 函数完全相同的风格作为 XML 文档返回。如果结果是由关系类型组成的,则在客户端作为有效流转换成 XML。如果 SQL 查询的结果已经是 XML,例如 FOR XML 查询或 XML 数据类型的查询,则使用该查询的结果。如果没有返回结果,像在大多数 T-SQL DML 语句的情况下,这解释为空文档,它是有效的。来自此 XQuery 的输出如下所示,它列出了用 Customers 元素包装的顾客表中所有的顾客。在结果中自动为表中的每一行创建行元素。草地chin ai tp owerbEvmRXs
<Customers>
<row>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
<ContactName>Maria Anders</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Address>Obere Str. 57</Address>
<City>Berlin</City>
<PostalCode>12209</PostalCode>
<Country>Germany</Country>
<Phone>030-0074321</Phone>
<Fax>030-0076545</Fax>
</row>
<row>
<CustomerID>ANATR</CustomerID>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
<ContactName>Ana Trujillo</ContactName>
<ContactTitle>Owner</ContactTitle>
<Address>Avda. de la Constitucion 2222</Address
<City>Mexico D.F.</City
<PostalCode>05021</PostalCode>
<Country>Mexico</Country>
<Phone>(5) 555-4729</Phone>
<Fax>(5) 555-3745</Fax>
</row>
...
</Customers>
为了通过 SQL Server 执行此查询,需要使用下面的代码。 草地chin ai tp owerbEvmRXs
static String ConnectionString = "database=Northwind;Data Source=localhost;Integrated Security=SSPI";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
XmlDataSourceResolver resolver = new XmlDataSourceResolver();
resolver.Add("conn", connection);
XQueryCommand xq = new XQueryCommand();
StreamReader reader = new StreamReader("query.xml");
xq.Compile(reader);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.ConformanceLevel = ConformanceLevel.Auto;
using (XmlWriter writer = XmlWriter.Create("output.xml", settings))
{
try
{
connection.Open();
xq.Execute(resolver, writer);
}
catch (Exception e)
{
Console.Out.WriteLine(e.Message);
Console.Out.WriteLine(e.InnerException.Message);
}
}
}
这里,XmlDataSourceResolver 类提供使数据库连接与 sql:query 调用内可以使用的名称相关联的角色。首先从名为 query.xml 的本地文件中读取该查询,再进行编译,然后创建 XmlWriter 来写入结果。需要注意 XmlWriter 中使用的 ConformanceLevel.Auto 设置,它自动检测创建片段还是创建文档,这是必要的,因为可以借此构造结果中的元素,XQuery 能够生成这两者。在执行查询之前,向数据库打开连接,然后执行查询,并将结果写入文件。草地chin ai tp owerbEvmRXs
sql:query 命令极其灵活而强大,它能够将有名称的参数提供给服务器上的 T-SQL 查询或调用的存储过程。sql:query 中命名的参数的作用完全等同于 System.Data.SqlClient 类。参数是在 T-SQL 查询中提供的,由后面紧跟名称的“@”表示。然后提供该名称和实际值之间的绑定作为查询的参数。对于每个命名的值,可以将相应的值(由序列中的位置决定)用于绑定。必须有与语言绑定数量相同的参数名称。下面的示例最好地对此进行了演示。草地chin ai tp owerbEvmRXs
declare namespace sql='http://schemas.microsoft.com/framework/2003/xml/sql';
let $country := "USA"
<Customers>{
for $customer in sql:query("select * from customers where Country = @country",
"conn", {"@country"}, {$country})
return $customer/PostalCode
}</Customers>
这里,将参数 country 提供给 T-SQL 查询,从而将 $country XQuery 变量绑定到 @country 参数。结果是所有美国顾客的邮政编码列表。草地chin ai tp owerbEvmRXs
sql:query 函数还可用于调用 T-SQL 存储过程(如果需要的话,就以上述方式传送参数)。下面的示例显示了如何调用 Northwind 数据库中的“Ten Most Expensive Products”存储过程,它没有输入参数。草地chin ai tp owerbEvmRXs
declare namespace sql ='http://schemas.microsoft.com/framework/2003/xml/sql';
for $prod in sql:query('Exec "Ten Most Expensive Products"', "conn")
return $prod