Chinaunix首页 | 论坛 | 博客
  • 博客访问: 669868
  • 博文数量: 759
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 4845
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-27 13:51
文章分类

全部博文(759)

文章存档

2011年(1)

2008年(758)

我的朋友

分类:

2008-10-27 13:58:16

        将 XML 数据从 SQL Server 2000 传输到 SQL Server 2005

        可以用多种方式将 XML 数据传输到 SQL Server 2005。在下一节中,我们将讨论几种方案。

        * 如果您将数据在 SQL Server 2000 数据库的 [n]text 或图像列中,可以使用 DTS 等将表导入到 SQL Server 2005 数据库中。使用 ALTER TABLE 语句将列类型更改为 XML。

        * 可以使用 bcp out 批量复制 SQL Server 2000 中的数据,使用 bcp in 将数据批量插入到 SQL Server 2005 数据库中。

        * 如果您将数据在 SQL Server 2000 数据库的关系列中,请创建一个带有一个 ntext 列的新表,同时根据需要在该表中创建一个主键列以用作行标识符。使用客户端编程检索在中通过 FOR XML 生成的 XML,并且将其写入 ntext 列。然后,使用上述技巧将数据传输到 SQL Server 2005 数据库。您可以选择将 XML 直接写入 SQL Server 2005 数据库的 XML 列中。

        示例:将列类型更改为 XML

        假设您需要将表 R 中的 [n]text 或图像列 XYZ 的类型更改为非类型化 XML。下面的语句可执行此类更改:

        ALTER TABLE R ALTER COLUMN XYZ XML

        * 如果需要,可以通过指定一个 XML 架构集合将目标类型化为 XML。

        批量加载 XML 数据

        可以使用 SQL Server 中的批量加载功能(如 bcp),将 XML 数据批量加载到中。通过 OPENROWSET 可以将文件中的数据加载到 XML 列中。下面的示例阐明了这一点。

        示例:从文件中加载 XML

        该示例说明了如何在表 T 中插入行。XML 列的值作为 CLOB 从文件 C:\yukon\xmlfile.xml 中加载,并且整数列被提供了值 10。

         INSERT INTO T
                    SELECT 10, xCol
                    FROM    (SELECT *
                    FROM OPENROWSET (BULK 'C:\Yukon\xmlfile.xml', SINGLE_CLOB)
                    AS xCol) AS R(xCol)

        文本编码

        SQL Server 2005 用 Unicode (UTF-16) 存储 XML 数据。从服务器中检索的 XML 数据采用 UTF-16 编码;如果您需要不同的编码,则需要对检索到的数据执行必要的转换。有时,您可能拥有采用不同编码的 XML 数据,因此在数据加载过程中需要非常小心:

        * 如果文本 XML 采用 Unicode (UCS-2, UTF-16),则将其赋给 XML 列、变量或参数不会带来任何问题。

        * 如果编码不是 Unicode 并且是隐式的(由于源代码页),则数据库中的字符串代码页应该与要加载的代码点相同或兼容(必要时使用 COLLATE)。如果不存在这样的服务器代码页,则您必须添加带有正确编码的显式 XML 声明。

        * 要使用显式编码,请使用 varbinary() 类型(它不与代码页交互)或者使用适当代码页的字符串类型。然后,将该数据赋给 XML 列、变量或参数。

        示例:显式指定编码

        假设您具有的 XML 文档 (vcdoc) 被存储为没有显式 XML 声明的 varchar(max)。下面的语句将添加一个带有编码"iso8859-1"的 XML 声明,将 XML 文档串连起来,将结果转换为 varbinary(max) 以便保留字节表示形式,最后将其转换为 XML。这使 XML 处理器能够按照指定的编码"iso8859-1"来分析数据,并为字符串值生成相应的 UTF-16 表示形式。

         SELECT CAST(
                    CAST ((''+ vcdoc)
                    AS VARBINARY (MAX))
                    AS XML)

        Xquery 与类型推理

        嵌入到 T-SQL 中的 XQuery () 语言支持查询 XML 数据类型。该语言正在由 WWW 联合会 (W3C) 进行开发(在本文作者最后一次召集起来撰写本文时),并且所有主要数据库供应商(包括 Microsoft)都参与了开发工作。它包括了 XPath 2.0 作为导航语言。同时,还提供了针对 XML 数据类型的数据修改语言构造。有关 SQL Server 2005 中支持的 Xquery 构造、函数和运算符的信息,请参阅联机图书。

        错误模型

        具有语法错误的 Xquery 表达式和 XML DML 语句会返回编译错误。编译阶段会检查 XQuery 表达式和 DML 语句的静态类型正确性,并且对于类型化 XML 使用 XML 架构进行类型推理。如果某个表达式可能在运行时由于类型冲突而失败,它会引发静态类型错误。静态错误的例子有将字符串添加到整数以及在不存在的节点中查询类型化数据。

        与 W3C 标准有所不同的是,XQuery 运行时错误被转换为可以作为空 XML 或 NULL 传播给查询结果的空序列(具体取决于调用上下文)。

        通过显式转换到正确的类型,用户可以避免静态错误,尽管运行时转换错误将被转化为空序列。

        下面的小节将详细讨论类型检查。

        唯一性检查

        如果编译器无法确定能否在运行时保证唯一性,则要求唯一性的定位步骤、函数参数和运算符(例如 eq)将返回错误。问题经常出现在非类型化数据上。例如,属性查找要求存在唯一的父元素;能够选择单个父节点的序号即可满足需要。计算 node()-value() 组合(请参阅 Value()、Nodes() 和 OpenXML())以提取属性值,这可能不需要指定序号,如下面的示例所示。

        示例:已知的唯一性

        在该示例中,nodes() 方法为每个 元素生成一个单独的行。(有关 nodes() 方法的详细说明,请参阅 Value()、Nodes() 和 OpenXML())。在 节点上进行求值的 value() 方法会提取 @genre(它作为属性具有唯一性)的值。

         SELECT nref.value(, 'varchar(max)') LastName
                    FROM   T CROSS APPLY xCol.nodes('//book') AS R(nref)

        XML 架构用于对类型化 XML 进行类型检查。如果节点被指定为 XML 架构中的唯一节点,则编译器将使用该信息,并且不会出现任何错误。否则,需要能够选择单个节点的序号。特别地,如果使用子代或自身轴 (//),例如 /book//title,则会丢失 <title>元素的唯一性基数推理,即使 XML 架构指定其具有这种性质。请将其改写为 (/book//title)[1]。

        对于类型检查,需要记住 //first-name[1] 和 (//first-name)[1] 之间的差别。前者返回 节点的序列,其中每个节点是其同辈节点中最左边的 节点。后者返回 XML 实例中按照文档顺序的第一个唯一的 节点。

        示例:value() 的用法

        下面这个对非类型化 XML 列执行的查询会导致静态、编译错误,因为 value() 需要将一个唯一性节点作为第一个参数,但编译器无法确定在运行时是否将只出现一个 节点:

         SELECT xCol.value('//author/last-name', 'nvarchar(50)') LastName
                    FROM   T

        您可能会尝试以下解决办法:

         SELECT xCol.value('//author/last-name[1]', 'nvarchar(50)') LastName
                    FROM   T

        但是,这不会纠正该错误,因为在每个 XML 实例中都可能出现多个 节点。下面的改写方式将会有效:

         SELECT xCol.value('(//author/last-name)[1]', 'nvarchar(50)') LastName
                    FROM   T
                    This query returns the value of the first  element in each XML instance.

        父轴

        如果节点的类型无法确定,则它将成为 anyType,后者不会隐式转换为任何其他类型。在使用父轴(例如,xCol.query())进行导航的过程中,尤其会发生这种情况;该父节点类型被确定为 anyType。元素也可能被定义为 XML 架构中的 anyType。在这两种情况下,丢失更为精确的类型信息通常会导致静态类型错误,并且要求将原子值显式转换为它们的特定类型。

        Data()、Text() 和 String() 访问器

        XQuery 具有一个可从节点中提取标量的、类型化值的函数 fn:data(),一个可返回文本节点的节点 text(),以及可返回节点的字符串值的函数 fn:string()。它们的用法有时会引起混乱。下面是有关在 SQL Server 2005 中正确使用它们的准则。请考虑 XML 实例 12:

        * 非类型化 XML:路径表达式 /age/text() 返回文本节点"12"。函数 fn:data(/age) 返回字符串值"12",fn:string(/age) 也是如此。

        * 类型化 XML:对于任何简单的类型化 元素,表达式 /age/text() 都会返回静态错误。另一方面,fn:data(/age) 返回整数 12,而 fn:string(/age) 会产生字符串"12"。

[1]  

【责编:michael】

--------------------next---------------------

阅读(486) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~