SQL Server 2005 包括对 Transact-SQL (T-SQL) 语言的几项重要改进。新增功能之一是一种新的触发器,它在数据定义语言 (DDL) 语句运行时激发。在跟踪或保护数据库对象的创建和修改,或对数据库服务器进行更改时,DDL 触发器非常有用。另一个新功能涉及异常处理,该功能因因包含TRY/CATCH 块而在异常处理方面向前飞跃了一大步。另一组新功能则以新的 XML 数据类型为中心,该数据类型在与 SQL Server 交互的企业应用程序中管理 XML 数据方面前进了一大部。现在,XML 文档或片段可以存储于 XML 列、绑定到架构、还可以利用 XQuery 语法查询。本文汇总各类问题来做出详细解答。
问:类型化和非类型化 XML 列各自的优势是什么?
答:非类型化 XML 列可以存储所有格式规范的 XML 片段或文档,而类型化 XML 列可以绑定到 XML 架构。如果不确定 XML 将遵循哪个架构,则非类型化 XML 很有用。例如,如果您必须使用另一个应用程序的某些 XML,但无法确定数据将遵循哪个 XML 架构,则可以使用非类型化 XML 列来执行这项工作。当然,非类型化 XML 也会带来其他问题。例如,不能针对某个架构编程,因此很难有效地使用 XML。但有时无法避免非类型化 XML。创建非类型化 XML 列非常简单,如下所示:
CREATE TABLE Foo(FooID INT, someXml XML) |
架构不绑定到 XML 列的另一个结果是,SQL Server® 2005 会将非类型化 XML 作为一个字符串存储。这是件好事还是坏事?实际上,既是好事也是坏事。将 XML 作为字符串存储使您可以更灵活地存储任何 XML 片段或文档。根据应用程序的业务规则,您可能需要这种方式。另一方面,将 XML 作为字符串存储意味着,与类型化 XML 相比,既不能有效地存储也不能有效地搜索 XML 数据。并且既不会告诉 SQL Server XML 将包含哪些内容,也不会告诉它层次结构和 XML 节点的数据类型。但请记住,仅仅因为这些是非类型化 XML 列并不意味着它们可以接受您设计出的任何格式。类型化和非类型化 XML 列仍然只接受格式规范的 XML。
如果您要存储架构已知的 XML 文档,类型化 XML 列很理想。架构可以定义元素、属性、它们的数据类型、需要哪些字段以及数据的整个层次结构。由于这种详细信息有关 XML 列的数据,因此 SQL Server 2005 可以在内部更加有效地存储 XML 数据。如果您尝试存储与架构不匹配的 XML 数据,则 SQL Server 会检测到这一点并阻止您。
创建类型化 XML 列就像在括号中添加架构名称一样简单,如下所示:
CREATE TABLE Foo(FooID INT, someXml XML(CONTENT FooSchema)) |
该语句指出 someXml 列必须遵循名为 FooSchema 的 XML 架构集合。通过分别包含相应的关键字 DOCUMENT 或 CONTENT,XML 可指定为必须是一个文档或者可以包含一个片段。如果省略,则默认值为 CONTENT。
可以使用 T-SQL 命令将 XML 架构集合添加到数据库中,如下所示:
CREATE XML SCHEMA COLLECTION [FooSchema] AS N 'put your schema here' |
也可以使用 SQL Server Management Studio (SSMS) 创建 XML 架构集合模板。从 View 菜单打开 Template Explorer,然后导航到 XML Schema Collections 节点并展开它。然后,您可以双击 CREATE 模板打开一个模板,该模板为您创建 XML 架构集合提供了一个良好的语法开端(参见图 1)。
图 1 XML 架构集合模板是 SSMS
SQL Server 2005 随附的 AdventureWorks 数据库有一个名为 HumanResources.JobCandidate 的表。该表包含一个名为 Resume 的列,该列是一个绑定到架构集合 HumanResources.HRResumeSchemaCollection 的 XML 列。该列中存储的所有 XML 数据都必须遵循该架构。
图 2 Resume 架构
类型化和非类型化 XML 列都可以进行索引,但索引时,绑定到架构的 XML 列比非类型化 XML 列具有更多优点。将 XML 索引应用于非类型化 XML 列时,必须分析大部分 XML 结构来定位匹配的节点。但是,将 XML 索引应用于类型化 XML 列时,特定节点是可识别的并可根据架构定位。因此,索引可以在类型化 XML 中更有效地工作,因为它知道在哪里查找。此外,如果需要搜索一个数值范围,则索引将用非类型化 XML 执行一个数据类型转换(因为数据类型是未知的)。类型化 XML 定义自己的数据类型,从而避免了转换开销。