1  /  1  页   1 跳转 查看:3819

高级XML处理

高级XML处理

--chenjing957翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
--原帖地址


在前面的文章里,我看到一些例子用来阐述在SQL Server2005中关于XML处理能力。我见过许多例子都是教我们如何从XML变量或域中读出其中的值。

在这一部分,我将看到不同的方式由查询结果来生成一个XML缓存或变量。大多数的时间你可能需要用到,如果你有必要在调用的函数或存储过程中采用XML作为参数。

使用TSQL中的FOR XML关键词将查询的结果转换成XML格式。FOR XML通常总是后面跟着关键词: AUTO,RAW,PATH或EXPLICIT,在这篇文章里我们将看到AUTO和RAW的用法.

例子:

第一步
    1 /*
    2    让我们创建一个实例表并初始化它.
    3 */
    4
    5 CREATE TABLE [dbo].[OrderDetails](
    6    [OrderDetailID] [int] IDENTITY(1,1) NOT NULL,
    7    [OrderNumber] VARCHAR(10) NOT NULL,
    8    [ItemNumber] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    9    [Qty] [int] NULL,
  10    [Rate] FLOAT NULL,
  11    [QtyPicked] INT NULL
  12 ) ON [PRIMARY]
  13
  14 INSERT INTO OrderDetails (OrderNumber, ItemNumber, Qty, Rate, QtyPicked)
  15    SELECT '00001', 'A001', 10, 11.25, 0
  16    UNION SELECT '00001', 'A002', 20, 15, 0
  17    UNION SELECT '00001', 'A003', 30, 23.75, 0


第二步
    1 /*
    2    用带AUTO参数的FOR XML返回一个XML格式的数据
    3    是最简单的事情.
    4 */
    5
    6 SELECT OrderNumber, ItemNumber, Qty FROM OrderDetails FOR XML AUTO
    7
    8 /*
    9 OUTPUT:
  10
  11 <OrderDetails OrderNumber="00001" ItemNumber="A001" Qty="10" />
  12 <OrderDetails OrderNumber="00001" ItemNumber="A002" Qty="20" />
  13 <OrderDetails OrderNumber="00001" ItemNumber="A003" Qty="30" />
  14 */


第三步
    1 /*
    2    尽管返回的结果具有XML格式,
    3    但它并不是XML数据类型. 结果是nvarchar类型.
    4    为了返回XML数据类型, 就用
    5    关键词TYPE.
    6 */
    7
    8 SELECT OrderNumber, ItemNumber, Qty FROM OrderDetails FOR XML AUTO, TYPE
    9
  10 /*
  11 OUTPUT:
  12
  13 <OrderDetails OrderNumber="00001" ItemNumber="A001" Qty="10" />
  14 <OrderDetails OrderNumber="00001" ItemNumber="A002" Qty="20" />
  15 <OrderDetails OrderNumber="00001" ItemNumber="A003" Qty="30" />
  16 */


第四步
    1 /*
    2    默认情况下, SQL SERVER 返回的是一个特征值.
    3    有时候你可能需要返回一个节点的值. 用
    4    ELEMENTS 关键词来实现吧.
    5 */
    6
    7 SELECT OrderNumber, ItemNumber, Qty FROM OrderDetails FOR XML AUTO, TYPE, ELEMENTS
    8
    9 /*
  10 OUTPUT:
  11
  12 <OrderDetails>
  13  <OrderNumber>00001</OrderNumber>
  14  <ItemNumber>A001</ItemNumber>
  15  <Qty>10</Qty>
  16 </OrderDetails>
  17 <OrderDetails>
  18  <OrderNumber>00001</OrderNumber>
  19  <ItemNumber>A002</ItemNumber>
  20  <Qty>20</Qty>
  21 </OrderDetails>
  22 <OrderDetails>
  23  <OrderNumber>00001</OrderNumber>
  24  <ItemNumber>A003</ItemNumber>
  25  <Qty>30</Qty>
  26 </OrderDetails>
  27 */


第五步
    1 /*
    2    你将会注意到这里的结果并没有 ROOT 元素.
    3    一个正确的 XML 文档/片断 都应该总会有一个 ROOT 元素.
    4    让我们增加一个 ROOT 关键词来搞定它.
    5 */
    6
    7 SELECT OrderNumber, ItemNumber, Qty FROM OrderDetails FOR XML AUTO, TYPE, ELEMENTS, ROOT
    8
    9 /*
  10 OUTPUT:
  11
  12 <root>
  13  <OrderDetails>
  14    <OrderNumber>00001</OrderNumber>
  15    <ItemNumber>A001</ItemNumber>
  16    <Qty>10</Qty>
  17  </OrderDetails>
  18  <OrderDetails>
  19    <OrderNumber>00001</OrderNumber>
  20    <ItemNumber>A002</ItemNumber>
  21    <Qty>20</Qty>
  22  </OrderDetails>
  23  <OrderDetails>
  24    <OrderNumber>00001</OrderNumber>
  25    <ItemNumber>A003</ItemNumber>
  26    <Qty>30</Qty>
  27  </OrderDetails>
  28 </root>
  29 */


第六步
    1 /*
    2    于是, 我现在也有 <root> 元素了. 但是名字好像不太合适.
    3    让我们改变 root 元素的名字吧.
    4 */
    5
    6 SELECT OrderNumber, ItemNumber, Qty FROM OrderDetails FOR XML AUTO, TYPE, ELEMENTS, ROOT('orderInfo')
    7
    8 /*
    9 OUTPUT:
  10
  11 <orderInfo>
  12  <OrderDetails>
  13    <OrderNumber>00001</OrderNumber>
  14    <ItemNumber>A001</ItemNumber>
  15    <Qty>10</Qty>
  16  </OrderDetails>
  17  <OrderDetails>
  18    <OrderNumber>00001</OrderNumber>
  19    <ItemNumber>A002</ItemNumber>
  20    <Qty>20</Qty>
  21  </OrderDetails>
  22  <OrderDetails>
  23    <OrderNumber>00001</OrderNumber>
  24    <ItemNumber>A003</ItemNumber>
  25    <Qty>30</Qty>
  26  </OrderDetails>
  27 </orderInfo>
  28 */


第七步
    1 /*
    2    直到现在, 我们看到了如何分配一个普通的名字给 <root> 元素就像
    3    每一行都拥有的名字一样. 它也可以给每一个拥有普通名字

    4    的元素起一个别名. 从下面的例子就可以看到.
    5 */
    6
    7 SELECT
    8    OrderNumber as 'OrderNum',
    9    ItemNumber as ItemCode,
  10    Qty as Quantity
  11 FROM OrderDetails FOR XML AUTO, TYPE, ELEMENTS, ROOT('itemInfo')
  12
  13 /*
  14 OUTPUT:
  15
  16 <itemInfo>
  17  <OrderDetails>
  18    <OrderNum>00001</OrderNum>
  19    <ItemCode>A001</ItemCode>
  20    <Quantity>10</Quantity>
  21  </OrderDetails>
  22  <OrderDetails>
  23    <OrderNum>00001</OrderNum>
  24    <ItemCode>A002</ItemCode>
  25    <Quantity>20</Quantity>
  26  </OrderDetails>
  27  <OrderDetails>
  28    <OrderNum>00001</OrderNum>
  29    <ItemCode>A003</ItemCode>
  30    <Quantity>30</Quantity>
  31  </OrderDetails>
  32 </itemInfo>
  33 */


第八步
    1 /*
    2    到现在, 我们看到了就像给列一样重命名 <root> 元素
    3    现在让我们看看如何给行重命名.
    4    默认的 AUTO 关键词生成的行

    5    所带的名字都是:表名/别名.
    6 */
    7
    8 SELECT
    9    OrderNumber,
  10    ItemNumber,
  11    Qty
  12 FROM OrderDetails itemInfo FOR XML AUTO, TYPE, ELEMENTS, ROOT('orderInfo')
  13
  14 /*
  15 OUTPUT:
  16
  17 <orderInfo>
  18  <itemInfo>
  19    <OrderNumber>00001</OrderNumber>
  20    <ItemNumber>A001</ItemNumber>
  21    <Qty>10</Qty>
  22  </itemInfo>
  23  <itemInfo>
  24    <OrderNumber>00001</OrderNumber>
  25    <ItemNumber>A002</ItemNumber>
  26    <Qty>20</Qty>
  27  </itemInfo>
  28  <itemInfo>
  29    <OrderNumber>00001</OrderNumber>
  30    <ItemNumber>A003</ItemNumber>
  31    <Qty>30</Qty>
  32  </itemInfo>
  33 </orderInfo>
  34 */


第九步
    1 /*
    2    在前面的例子里, 我们给表分配了别名
    3    为了推广每一行元素的名字. 这个方法工作的不错.
    4    然而, 如果是复合式查询,有时候它将非常困惑于
    5    在XML格式中采用别名.
    6
    7    AUTO关键词并没有采用一种方式来定制行的名字. 通过采用
    8    RAW关键词, 而不是AUTO, 我们能够很容易的定制行. 在接下来的
    9    例子将详细阐述如果使用RAW 关键词.
  10 */
  11
  12 SELECT
  13    OrderNumber,
  14    ItemNumber,
  15    Qty
  16 FROM OrderDetails FOR XML RAW('itemInfo'), TYPE, ELEMENTS, ROOT('orderInfo')
  17
  18 /*
  19 OUTPUT:
  20
  21 <orderInfo>
  22  <itemInfo>
  23    <OrderNumber>00001</OrderNumber>
  24    <ItemNumber>A001</ItemNumber>
  25    <Qty>10</Qty>
  26  </itemInfo>
  27  <itemInfo>
  28    <OrderNumber>00001</OrderNumber>
  29    <ItemNumber>A002</ItemNumber>
  30    <Qty>20</Qty>
  31  </itemInfo>
  32  <itemInfo>
  33    <OrderNumber>00001</OrderNumber>
  34    <ItemNumber>A003</ItemNumber>
  35    <Qty>30</Qty>
  36  </itemInfo>
  37 </orderInfo>
  38 */


第十步
    1 /*
    2    到目前为止, 我们能够用我们自己的方式格式化XML的结果.
    3    我们能够重命名root节点,行和元素名称.
    4
    5    现在让我看一个不同的例子. 在SQL Server生成
    6    XML 结果的时候, 它将遍历列中每一个null值.
    7    让我们看这个例子.
    8
    9    下面的代码, 更新列为null. 然后看看结果. 
  10    第三行并没有 <Qty> 元素.
  11 */
  12
  13 UPDATE OrderDetails SET Qty = NULL WHERE OrderDetailID = 3
  14
  15 SELECT
  16    OrderNumber,
  17    ItemNumber,
  18    Qty
  19 FROM OrderDetails FOR XML RAW('itemInfo'), TYPE, ELEMENTS, ROOT('orderInfo')
  20
  21 /*
  22 OUTPUT:
  23
  24 <orderInfo>
  25  <itemInfo>
  26    <OrderNumber>00001</OrderNumber>
  27    <ItemNumber>A001</ItemNumber>
  28    <Qty>10</Qty>
  29  </itemInfo>
  30  <itemInfo>
  31    <OrderNumber>00001</OrderNumber>
  32    <ItemNumber>A002</ItemNumber>
  33    <Qty>20</Qty>
  34  </itemInfo>
  35  <itemInfo>
  36    <OrderNumber>00001</OrderNumber>
  37    <ItemNumber>A003</ItemNumber>
  38  </itemInfo>
  39 </orderInfo>
  40 */


第十一步
    1 /*
    2    在前面的例子中,我们可以看到如果列是NULL,
    3    则元素将在生成XML的时候不被现实或者叫做不存在.
    4
    5    你在大多数情况下都能发现这个问题. 例如, 比如我们
    6    需要传递一个XML片断到另一个函数或者存储过程中并且如果
    7    这个函数或者存储过程希望元素中存在所有行
    8    那个这个函数或者存储过程将通知失败.
    9
  10    所以, 我们需要用一种方式将值为空的元素显现出来.
  11    关键词XSINIL就能做到这一点.
  12 */
  13
  14 SELECT
  15    OrderNumber,
  16    ItemNumber,
  17    Qty
  18 FROM OrderDetails FOR XML RAW('itemInfo'), TYPE, ELEMENTS XSINIL, ROOT('orderInfo')
  19
  20 /*
  21 OUTPUT:
  22
  23 <orderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
  24  <itemInfo>
  25    <OrderNumber>00001</OrderNumber>
  26    <ItemNumber>A001</ItemNumber>
  27    <Qty>10</Qty>
  28  </itemInfo>
  29  <itemInfo>
  30    <OrderNumber>00001</OrderNumber>
  31    <ItemNumber>A002</ItemNumber>
  32    <Qty>20</Qty>
  33  </itemInfo>
  34  <itemInfo>
  35    <OrderNumber>00001</OrderNumber>
  36    <ItemNumber>A003</ItemNumber>
  37    <Qty xsi:nil="true" />
  38  </itemInfo>
  39 </orderInfo>
  40 */


最后编辑chenjing957 最后编辑于 2007-06-08 17:26:44
SQL Server技术交流群:71791281(有些问题在线解决或许会更快)

本群将从即日起严厉打击:刷屏、打广告、粘贴各种垃圾信息的ID,一经发现,马上删除。

希望通过我们的努力,能为大家打造一个健康有序的交流平台。
 

回复: 高级XML处理

ding yige  :lol
 

回复: 高级XML处理

Mark.
 
1  /  1  页   1 跳转

版权所有 微软BI开拓者 

Powered by Discuz!NT 2.1.202    Copyright © 2001-2012 Comsenz Inc.
Processed in 0.0937536 second(s) , 4 queries.
返顶部