MS SQL SERVER2005 XML 最佳实践12

时间:2021-09-15 23:39:56

V 视图包含一个行,该行只有一个 XML 类型的 columnxmlVal。可以查询像常规 xml 数据类型实例那样对它进行查询。例如,下面的查询返回名字为“David”的作者:

  复制代码
SELECT xmlVal.query('//author[first-name = "David"]')FROM   V
 

SQL 视图定义与使用带批注的架构创建的 XML 视图有些相似。但二者之间存在重要的差异。SQL 视图定义是只读的,且必须使用嵌入式 XQuery 来操作。XML 视图是通过使用带批注的架构创建的。此外,SQL 视图在应用 XQuery 表达式之前具体化 XML 结果,而对 XML 视图的 XPath 查询是对基础表计算 SQL 查询。

添加业务逻辑
可以采用多种方式将业务逻辑添加到 XML 数据中:

您可以编写行或列约束,以在插入和修改 XML 数据时强制实施特定于域的约束。


您可以在 XML 列上编写插入或更新列中的值时激发的触发器。该触发器可以包含特定于域的验证规则或填充属性表。


您可以采用托管代码编写 SQLCLR 函数并将向其传递 XML 值,并且使用 System.Xml 命名空间提供的 XML 处理功能。例如,将 XSL 转换应用到 XML 数据。另外,您可以将 XML 反序列化为一个或多个托管类,并使用托管代码对它们进行操作。


您可以编写 Transact-SQL 存储过程和函数,对 XML 列进行处理以满足业务需要。


示例:应用 XSL 转换
例如,CLR 函数 TransformXml(),它接受 xml 数据类型实例和文件中存储的 XSL 转换,将转换应用到 XML 数据,然后在结果中返回转换的 XML。以下是用 C# 编写的主干函数:

  复制代码
public static SqlXml TransformXml (SqlXml XmlData, string xslPath) {   // Load XSL transformation   XslCompiledTransform xform = new XslCompiledTransform();   XPathDocument xslDoc = new XPathDocument (xslPath);   xform.Load(xslDoc);   // Load XML data    XPathDocument xDoc = new XPathDocument (XmlData.CreateReader());   // Return the transformed value   MemoryStream xsltResult = new MemoryStream();   xform.Transform(xDoc, null, xsltResult);   SqlXml retSqlXml = new SqlXml(xsltResult);   return (retSqlXml);}
 

在注册了程序集并创建了与 TransformXml() 对应的用户定义 Transact-SQL 函数 SqlXslTransform() 之后,就可以从 Transact-SQL 中调用该函数,如下面的查询所示:

  复制代码
SELECT SqlXslTransform (xCol, 'C:/MyFile/xsltransform.xsl')FROM    TWHERE  xCol.exist('/book/title/text()[contains(.,"custom")]') =1
 

查询结果包含转换的 XML 的行集。

SQLCLR 扩展了这样一些功能:将 XML 数据分解到多个表或属性提升,以及通过使用 System.Xml 命名空间中的托管类查询 XML 数据。有关详细信息,请参阅 SQL Server 联机丛书和 .Net Framework SDK 文档。

跨域查询
当您的数据同时保存在关系和 xml 数据类型列中时,您可能希望编写将关系和 XML 数据处理结合起来的查询。例如,您可以通过使用 FOR XML 将关系列和 XML 列中的数据转换为 xml 数据类型实例,并使用 XQuery 对其进行查询。相反,您可以从 XML 值生成行集,并使用 Transact-SQL 对其进行查询。

一种编写跨域查询的更方便且有效的方法是在 XQuery 或 XML DML 表达式中使用 SQL 变量或列的值:

您可以在 XQuery 或 XML DML 表达式中,通过使用 sql:variable() 来使用 SQL 变量的值。


您可以在 XQuery 或 XML DML 表达式中,通过使用 sql:column() 来使用关系列中的值。


通过这两种方法,应用程序可以对查询进行参数化,如以下示例所示。但在 sql:variable() 和 sql:column() 中不允许使用 XML 和用户定义类型。

示例:使用 sql:variable() 的跨域查询
下面的查询是“示例:对基于 xml 数据类型方法的计算列的查询”中所示查询的修改版本。在下面的版本中,使用 SQL 变量 @isbn 传入了此特定 ISBN。通过将常量替换为 sql:variable(),可以使用查询来搜索任何 ISBN,而不仅是 ISBN 为 0-7356-1588-2 的书。