硬盘数据恢复导航
RAID数据恢复导航
 | 网站首页 | 数据恢复资料 | 数据恢复软件 | 咨询留言 | 数据恢复博客 | 数据恢复论坛 | 
数据恢复软件下载
公司简介 数据恢复成功案例 数据恢复报价 数据恢复培训 数据恢复技术文章 数据恢复客服中心 数据恢复服务联系方式
您现在的位置: 北亚数据恢复技术站 >> 数据恢复资料 >> 相关编程资料 >> 文章正文
MSSQL 使用 EXPLICIT 模式一            【字体:
MSSQL 使用 EXPLICIT 模式一
作者:未知    文章来源:网络    点击数:    更新时间:2009-7-28

在 EXPLICIT 模式中,查询书写器控制由执行查询所返回的 XML 文档的形式。必须以特定的方

式编写查询,将有关预期嵌套的附加信息显式指定为查询的一部分。可用 directive 在列级指定附

加的配置。当指定EXPLICIT 模式时,必须负责确保生成的 XML 符合语法规则并且有效(对于

XML-DATA 架构)。

 

1、处理 EXPLICIT 模式查询和通用表
    EXPLICIT 模式将查询执行所得到的行集转换为 XML 文档。为使 EXPLICIT 模式生成 XML 文

档,行集必须具有特定的格式。这需要以某种方式编写 SELECT 查询以生成具有特定格式的行集(

称为通用表),可对该行集进行处理以生成请求的 XML 文档。

 

    EXPLICIT 模式首先要求查询生成两个元数据列:

    (1) 在 SELECT 子句中指定的第一列必须是命名 (Tag) 标记号。Tag 列存储当前元素的标记

              号。Tag 是整型数据类型。

    (2) 指定的第二列必须是父元素的命名 (Parent) 标记号。Parent 列存储父元素的标记号。


     这些列用于确定 XML 树中的父子层次结构。这些信息随后用于生成预期的 XML 树。如果存储在

Parent 列中的父标记值是 0 或 NULL,则将行放置在 XML 层次结构的顶层。

     通用表的其余部分充分描述所得到的 XML 文档。行集(通用表)中的数据垂直分区成组。每组

成为结果中的一个 XML 元素。

     FOR XML EXPLICIT 模式要求 SELECT 查询以某种方式指定通用表中的列名。它要求

SELECT 查询将元素名与标记号相关联,并提供通用表列名中的特性名(默认情况下是特性名)。此

外,若要得到与父实例相关联的正确子实例,需要对行集排序,使子实例紧跟在它的父实例后。简言

之,通用表的列名、Tag 和 Parent 元列中的值以及通用表格式的数据所提供的信息都用于生成所期

望的 EXPLICIT 模式的 XML 文档。

 

     SELECT 查询还必须指定通用表中的列名。通用表中的列名使用 XML 类属标识符和特性名进行编

码。通用表列名中的元素名、特性名和其它转换信息的编码被指定为:

       ElementName!TagNumber!AttributeName!Directive

 

参数
ElementName

     是所得到的元素类属标识符(例如,如果将 Customers 指定为 ElementName,则

     <Customers> 是元素标记)。

TagNumber

     是元素的标记号。借助于通用表中的两个元数据列(Tag 和 Parent),TagNumber

     用于表示 XML 树中的 XML元素嵌套。每个 TagNumber 都准确对应于一个 ElementName。

AttributeName

     是 XML 特性的名称(如果没有指定 Directive)或包含的元素名(如果 Directive 是

      xml、cdata 或 element)。
     如果指定 Directive,则 AttributeName 可以为空。这种情况下,列中包含的值直接

     由具有指定 ElementName 的元素所包含。

Directive

     是可选命令。如果没有指定 Directive,则必须指定 AttributeName。如果没有指定

     AttributeName 且没有指定 Directive(如 Customer!1),则表示元素命令(如

     Customer!1!!element)且包含数据。

     Directive 有两种用途。该选项用于分别使用关键字 ID、IDREF 和 IDREFS 对 ID、

     IDREF 和 IDREFS 进行编码。还用于表示如何使用关键字 hide、element、xml、xmltext

     和 cdata 将字符串数据映射到 XML。大多数情况下允许在这些组中组合指令,但是不能

     在组本身中进行组合。

ID
     可将元素特性指定为 ID 类型的特性。然后可以使用 IDREF 和 IDREFS 特性引用它们,

     以启用文档内的链接。但是,如果没有请求 XMLDATA,则此关键字无效。

IDREF
     指定为 IDREF 的特性可用于引用 ID 类型的特性,以启用文档内的链接。但是,如果没有

     请求 XMLDATA,则此关键字无效。

IDREFS
     指定为 IDREFS 的特性可用于引用 ID 类型的特性,以启用文档内的链接。但是,如果没

     有请求 XMLDATA,则此关键字无效。

hide
     不显示特性。这对于按照不出现在结果中的特性对结果进行排序可能很有用。

element
     不生成特性。而是生成具有指定名称的包含元素(如果没有指定特性名则直接生成包含元素)。

     包含数据被编码为实体(例如,字符 < 变成 &lt;)。该关键字可以与 ID、IDREF 或

     IDREFS 组合。

xml
     除了不进行实体编码外,该命令与元素命令相同(例如,字符 < 仍是 <)。除了 hide 外,

     该命令不能与任何其它命令一起使用。

xmltext
     列内容应包在单个标记内,以便与文档的其它部分集成。在提取 OPENXML 存储在列中的

     溢出(未用完的)XML 数据时该命令很有用。有关更多信息,请参见使用 OPENXML 编写

     XML。 如果指定了 AttributeName,则标记名由指定名称替换;
     否则通过将内容放在容器的起始处而不进行实体编码,将特性追加到包含元素的当前特性列表。

     含有该命令的列必须是文本类型(varchar、nvarchar、char、nchar、text、ntext)。

     该命令只能与 hide 一起使用。在提取存储在列中的溢出数据时该命令很有用。

     如果内容不是有效的 XML,则该行为不明确。


cdata
     通过用 CDATA 节环绕数据来包含数据。不对内容进行实体编码。原始数据类型必须是文本

     类型(varchar、nvarchar、text、ntext)。该命令只能与 hide 一起使用。当使用该命

     令时,不应指定 AttributeName。 


 

2、示例

 

示例 A 和 B 详细说明了编写使用 EXPLICIT 模式的查询的过程。该过程适用于后面的其它示例。

 

A. 检索客户和订单信息
下例检索客户和订单信息。假定希望生成下面的层次结构:

<Customer CustomerID="ALFKI">

<Order OrderID=10643>
     <Order OrderID=10692>

       ...

</Customer>
<Customer CustomerID="ANATR" >

<Order OrderID=10308 >
     <Order OrderID=10625 >

       ...

</Customer>

 

    生成所得到的 XML 树的查询生成通用表,该表包含两个元数据列:Tag 和 Parent。因此,在

指定查询时 SELECT 子句必须指定这两列。这两列中的值用于生成 XML 层次结构。

    <Customer> 元素位于顶层。在下面的示例中,指派给此元素的 Tag 值为 1(该值可以是任

何数字,但是有唯一的数字与每个元素名相关联)。因为 <Customer> 是顶层元素,所以其

Parent 标记值为 NULL。

    <Order> 元素是 <Customer> 元素的子元素。因此,<Order> 元素的 Parent 标记值为 1

(将 <Customer> 标识为其父元素)。指派给 <Order> 元素的 Tag 值为 2。

 

    可使用两个 SELECT 语句编写查询并使用 UNION ALL 组合这两个语句的结果:

    在第一个 SELECT 语句中,获取所有 <Customer> 元素及其特性值。在含有多个 SELECT

语句的查询中,只使用在第一个查询中指定的列名(通用表列名)。忽略在第二个 SELECT 语句中

指定的列名。因此,指定 XML 元素和特性名的通用表的列名包含在下面的查询中:


SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID]
FROM Customers

 

    在第二个查询中检索所有 <Order> 元素及其特性值:


SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID

 

     使用 UNION ALL 组合此查询中的两个 SELECT 语句。


     以只进方式对通用表行集(包含所有数据和元数据)逐行扫描,以生成所得到的 XML 树。为了

输出正确的 XML 文档层次结构,指定通用表中的行顺序也很重要。为此可在查询中使用 ORDER BY

子句。


    下面是最终查询:


SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID]
FROM Customers

UNION ALL
SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID], [Order!2!OrderID]
FOR XML EXPLICIT

 

     所得到的通用表是有四列的表。为了举例说明,只显示几行。

 

Tag      Parent       Customer!1!CustomerID         Order!2!OrderID
1          NULL         ALFKI                                       NULL
2         1                ALFKI                                       10643
2         1                ALFKI                                       10692
2         1                ALFKI                                       10702
2         1                ALFKI                                       11011
2         1                ALFKI                                        ...
1         NULL          ANATR                                       NULL
2         1                ANATR                                      10308
2         1                ANATR                                      10625
2         1                ANATR                                      ...

 


     下面描述处理通用表中的行以生成所得到的 XML 树:

      第一行标识 Tag 值 1。标识所有含有 Tag 值 1 的列。只有一列含有 Tag 值 1:

Customer!1!CustomerID。此列名由元素名 (Customer)、标记号 (1) 和特性名 (CustomerID)

组成。因此,创建 <Customer> 元素并向其添加特性 CustomerID。然后将该列值指派为该特性值。


      第二行有 Tag 值 2。因此,标识所有含有 Tag 值 2 的列。只有一列含有 Tag 值 2:

Order!2!OrderID。此列名由元素名 (Order)、标记号 (2) 和特性名 (OrderID) 组成。该行也将

<Customer> 标识为其父元素(Parent 值为 1)。结果,创建 <Order> 元素作为 <Customer>

元素的子元素并向其添加特性 OrderID。然后将该列值指派为该特性值。


     以相同的方式处理后面含有 Tag 值 2 的所有行。


     标识含有 Tag 值 1 的某行。标识含有 Tag 值 1 的 Customer!1!CustomerID 列。该列标识

没有父元素(Parent 为 NULL)的 <Customer> 元素。因而,关闭前面的 <Order> 标记和

<Customer> 标记。打开新的 <Customer> 标记并重复此过程。
     因为没有在查询中指定 Directive,所以特性名是 XML 特性的名称。下面是部分结果集:

 

<Customer CustomerID="ALFKI">
  <Order OrderID="10643" />
  <Order OrderID="10692" />
  <Order OrderID="10702" />
  <Order OrderID="11011" />
</Customer>
<Customer CustomerID="ANATR">
  <Order OrderID="10308" />
  <Order OrderID="10625" />
</Customer>

 

 

B. 指定元素命令


     下例检索客户和订单信息。假定希望生成下面的层次结构:(注意 <OrderID> 是 <Order> 的子元素

而不是特性):

 

<Customer CustomerID="ALFKI">
   <Order OrderDate="1997-08-25T00:00:00">
      <OrderID>10643</OrderID>
   </Order>
   <Order OrderDate="1997-10-03T00:00:00">
      <OrderID>10692</OrderID>
   </Order>
    ...
</Customer>

 

     <Customer> 元素位于顶层。在下例中,为 <Customer> 指派 Tag 值 1。因为 <Customer> 为顶

层元素,所以其Parent 标记值为 NULL。

     <Order> 元素是 <Customer> 元素的子元素。因此,<Order> 元素的 Parent 标记值为 1(将

<Customer> 标识为其父元素),并为其指派 Tag 值 2。

     <Order> 元素具有作为包含元素(不是特性)的 <OrderID>。因此,在检索该值时,必须指定 element

命令。可使用两个 SELECT 语句编写查询,并使用 UNION ALL 组合这两个语句的结果:

     在第一个 SELECT 语句中,获取所有 <Customer> 元素及其特性值。在含有多个 SELECT 语句的查

询中,只使用在第一个查询中指定的列名(通用表列名)。忽略在第二个 SELECT 语句中指定的列名。因此,

指定 XML 元素和特性名的通用表的列名包含在下面的查询中:


SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID!element],
         NULL                 as [Order!2!OrderDate]
FROM Customers

 

    在第二个查询中检索所有 <Order> 元素及其特性值。因为需要使用 ORDER BY 子句对含有子元素的父

元素进行分组,所以该查询选择 Customers.CustomerID。


SELECT 2, 1,
         Customers.CustomerID,
         Orders.OrderID,
         Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID

 

     使用 UNION ALL 组合此查询中的两个 SELECT 语句。


     使用 ORDER BY 子句指定所生成的通用表行集中的行顺序。


     下面是最终查询:


SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID!element],
         NULL                 as [Order!2!OrderDate]
FROM Customers

UNION ALL
SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID,
         Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID], [Order!2!OrderID!element]
FOR XML EXPLICIT

 

     所得到的通用表是有五列的表。为了举例说明,只显示几行。


Tag  Parent    Customer!1!CustomerID      Order!2!OrderID!element      Order!2!OrderDate
1      NULL      ALFKI                                    NULL                                       NULL
2     1             ALFKI                                    10692                                    1997-10-03T00:00:00
2     1             ALFKI                                    10702                                    1997-10-13T00:00:00
2     1             ALFKI                                    10835                                    1998-01-15T00:00:00
...    ...            ...                                          ...                                           ...
1     NULL       ANATR                                   10308                                    1996-09-18T00:00:00
1     NULL       ANATR                                   ...                                            ...


      下面描述对行集中的行进行处理以生成所得到的 XML 树:

       第一行标识 Tag 值 1。因此,标识所有含有 Tag 值 1 的列。只有一列含有 Tag 值 1:

Customer!1!CustomerID列。此列名由元素名 (Customer)、标记号 (1) 和特性名 (CustomerID)

组成。因此,创建 <Customer> 元素并向其添加特性 CustomerID。然后将该列值指派为该特性值。


       第二行含有 Tag 值 2。标识含有 Tag 值 2 的所有列。有两列含有 tag号 2:

Order!2!OrderID!element 和 Order!2!OrderDate。 列名 Order!2!OrderDate 由元素名

 (Order)、标记号 (2) 和特性名 (OrderDate) 组成。该行将 <Customer>标识为其父元素(Parent

值为 1)。因此,创建 <Order> 元素作为 <Customer> 元素的子元素并向其添加特性 OrderID。将

该列值指派为该特性值。列名 Order!2!OrderID!element 由命令 (element) 组成。因此,生成一个

包含元素 (<OrderID>)。将该列值指派为该元素值。


       以相同的方式处理后面含有 Tag 值 2 的所有行。


       标识含有 Tag 值 1 的某行。标识含有 Tag 值 1 的 Customer!1!CustomerID 列。该列标识

没有父元素(Parent 为 NULL)的 <Customer> 元素。因而,关闭前面的 <Order> 标记和

<Customer> 标记。打开新的 <Customer> 标记并重复此过程。

 

       说明:  在此查询中,如果更改列名 (Order!2!OrderID!element) 以便不指定特性名

(Order!2!!element),则该查询直接生成包含元素。

 

C. 指定 element 命令和实体编码


      如果将 directive 设置为 element,则对包含数据进行实体编码。例如,如果在 Customers 表中

有一位客户联系人的姓名是 Mar<ia Anders,则下面的查询将对所包含的数据进行编码:

 

--Update customer record.
UPDATE Customers
SET ContactName='Mar<ia Anders'
WHERE ContactName='Maria Anders'
GO

 

      下面的查询返回客户 ID 和联系人姓名信息。

      编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程,与在示例

A 或示例 B 中描述的过程相似。

 

SELECT 1 as Tag, NULL as Parent,
       Customers.CustomerID as [Customer!1!CustomerID],
       Customers.ContactName as [Customer!1!ContactName!element]
FROM Customers
ORDER BY [Customer!1!CustomerID]
FOR XML EXPLICIT
GO
-- set the value back to original
UPDATE Customers
SET ContactName='Maria Anders'
WHERE ContactName='Mar<ia Anders'
GO

 

      下面显示部分结果。因为在查询中指定了 element 命令,所以指定的特性名是包含元素的名称。也

对 ContactName 进行实体编码(将 ContactName 中的 < 字符返回为 &lt;)

 

<Customer CustomerID="ALFKI">
  <ContactName>Mar&lt;ia Anders</ContactName>
</Customer>
<Customer CustomerID="ANATR">
  <ContactName>Ana Trujillo</ContactName>
</Customer>

文章录入:a    责任编辑:a 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    关于我们 | RAID数据恢复 | 友情链接 | RSS生成 | XML生成 | 文章HTML地图 | 下载HTML地图

    版权所有 北亚数据恢复中心
    全国统一客服电话:4006-505-808
    北京市海淀区永丰基地丰慧中路7号新材料创业大厦B座205室
    京ICP备05011939