zoukankan      html  css  js  c++  java
  • 使用 FOR XML EXPLICIT

    使用 FOR XML EXPLICIT(转)

     http://blog.sina.com.cn/s/blog_677b66170100jsve.html

    使用 FOR XML EXPLICIT


    使用 FOR XML EXPLICIT,您可以控制查询返回的 XML 文档的结构。查询必须用特定的方法编写,让查询结果中指定有关您需要的嵌套的信息。使用 FOR XML EXPLICIT 支持的可选指令,您可以配置各列的处理方式。例如,您可以控制让列显示为元素或显示为属性内容,或者,列只用来给结构排序,而不出现在生成的 XML 中。

    有关如何使用 FOR XML EXPLICIT 编写查询的示例,请参见编写 EXPLICIT 模式的查询

    参数 

    在 EXPLICIT 模式中,SELECT 语句中的前两列必须分别命名为 Tag 和 Parent。Tag 和 Parent 是元数据列,它们的值用来确定查询返回的 XML 文档中元素的父子关系,也就是嵌套。

    • Tag 列    这是在选择列表中指定的第一列。Tag 列存储当前元素的标记值。标记号可以使用的值是 1 到 255。

    • Parent 列    这一列存储当前元素的父级的标记号。如果这一列中的值是 NULL,该行就会被放置在 XML 层次结构的顶层。

    例如,有这样一个查询,在没有指定 FOR XML EXPLICIT 时,它会返回下面的结果集。(first_name!1 和id!2 数据列的用途会在下一节给查询添加数据列中介绍)。

    TagParentfirst_name!1id!2
    1 NULL 'Beth' NULL
    2 NULL NULL '102'

    在这个示例中,Tag 列中的值是结果集中各元素的标记号。两行的 Parent 列都包含 NULL 值。这就是说,两个元素都会在层次结构的顶层生成,在查询包括 FOR XML EXPLICIT 子句时,会给出以下结果:

    <first_name>Beth</first_name> <id>102</id>

    但是,如果第二行在 Parent 列中的值是 1,结果看起来就会像下面这样:

    <first_name>Beth <id>102</id> </first_name>

    有关如何使用 FOR XML EXPLICIT 编写查询的示例,请参见编写 EXPLICIT 模式的查询

    给查询添加数据列 

    除了 Tag 列和 Parent 列以外,查询还必须包含一个或多个数据列。这些数据列的名称控制着在标记过程中解释列的方式。每个列名都拆分为由惊叹号 (!) 分隔的字段。可以为数据列指定以下字段:

    ElementName!TagNumber!AttributeName!Directive

    ElementName    元素的名称。对于给定的行,会从标记号匹配的第一列的 ElementName 字段中提取为该行生成的元素的名称。如果有多个 TagNumber 相同的列,对于后面的 TagNumber相同的列,会忽略 ElementName。在上面的示例中,第一行会生成一个名为 <first_name> 的元素。

    TagNumber    元素的标记号。对于有给定标记值的行,所有在其 TagNumber 字段中具有相同值的列都会向对应该行的元素提供内容。

    AttributeName    指定列值是 ElementName 元素的属性。例如,如果数据列具有名称 prod_id!1!color,那么 color 就会显示为 <prod_id> 元素的属性。

    Directive    使用这个可选字段,您可以进一步控制 XML 文档的格式。您可以为 Directive 指定以下值中的任何一个:

    • hide    指明此列会为生成结果而被忽略。这条指令可以用于加入只用来给表排序的列。属性名会被忽略,而且不出现在结果中。

      有关使用 hide 指令的示例,请参见使用 hide 指令

    • element    指明列值作为使用名称 AttributeName 的嵌套元素插入,而不是作为属性。

      有关使用 element 指令的示例,请参见使用 element 指令

    • xml    指明列值插入时不加引号。如果指定了 AttributeName,则值作为使用该名称的元素插入。否则,它在插入时没有包装元素。如果不使用此指令,标记字符就会被转义,除非列是 XML 类型。例如,值<a/> 会插入为 &lt;a/&gt;

      有关使用 xml 指令的示例,请参见使用 xml 指令

    • cdata    指明列值要作为 CDATA 节插入。AttributeName 会被忽略。

      有关使用 cdata 指令的示例,请参见使用 cdata 指令

    用法 

    在您执行包含 FOR XML EXPLICIT 的查询时,BINARY、LONG BINARY、IMAGE 和 VARBINARY 列中的数据会自动以 base64 编码格式返回。缺省情况下,结果集中的任何 NULL 值都会被忽略。通过更改 FOR_XML_NULL_TREATMENT 选项的设置,您可以更改这种行为。

    有关 FOR_XML_NULL_TREATMENT 选项的详细信息,请参见 FOR_XML_NULL_TREATMENT 选项 [database] 和 FOR XML 和 NULL 值

    编写 EXPLICIT 模式的查询 

    假定您要使用 FOR XML EXPLICIT 编写一个生成以下 XML 文档的查询:

    <employee emp_id='129'> <customer cust_id='107' region='Eastern'/> <customer cust_id='119' region='Western'/> <customer cust_id='131' region='Eastern'/> </employee>
    <employee emp_id='195'> <customer cust_id='109' region='Eastern'/> <customer cust_id='121' region='Central'/> </employee>

    实现这一点的方法是:编写一条按指定的准确顺序返回以下结果集的 SELECT 语句,然后将 FOR XML EXPLICIT 附加到该查询。

    TagParentemployee!1!emp_idcustomer!2!cust_idcustomer!2!region
    1 NULL 129 NULL NULL
    2 1 129 107 Eastern
    2 1 129 119 Western
    2 1 129 131 Central
    1 NULL 195 NULL NULL
    2 1 195 109 Eastern
    2 1 195 121 Central

    在您编写查询时,对于指定的行,只有部分列会成为所生成的 XML 文档的组成部分。只有在 TagNumber 字段(列名中的第二个字段)中的值与 Tag 列中的值匹配时,XML 文档中才会加入一列。

    在该示例中,第三列用于两个在其 Tag 列中有值 1 的行。在第四和第五列中,值用于在其 Tag 列中有值 2 的行。元素名从列名中的第一个字段中提取。在这种情况下,会创建 <employee> 元素和 <customer> 元素。

    属性名来自列名中的第三个字段,所以 emp_id 属性是为 <employee> 元素创建的,而 cust_id 属性和 region 属性是为 <customer> 元素生成的。

    下面的步骤说明了如何使用示例数据库来构建一个 FOR XML EXPLICIT 查询,让该查询生成一个与本节开始时出现的 XML 文档类似的 XML 文档。

    编写 FOR XML EXPLICIT 查询

    1. 编写 SELECT 语句以生成顶层元素。

      在本示例中,查询中的第一个 SELECT 语句生成 <employee> 元素。查询中的前两个值必须是 Tag 和 Parent 列值。<employee> 元素位于层次结构的顶层,所以会给它分配一个 Tag 值 1 以及一个 Parent 值 NULL。

      注意 
      如果您要编写一个使用 UNION 的 EXPLICIT 模式查询,则只有第一条 SELECT 语句中指定的列名才会被使用。不会用作元素名或属性名的列名必须在第一条 SELECT 语句中指定,因为在后面的 SELECT 语句中指定的列名会被忽略。

      要为上面的表生成 <employee> 元素,您的第一条 SELECT 语句要像下面这样:

      SELECT 1 AS tag, NULL AS parent, emp_id AS [employee!1!emp_id], NULL AS [customer!2!cust_id], NULL AS [customer!2!region] FROM employee
    2. 编写 SELECT 语句来生成子元素。

      第二个查询会生成 <customer> 元素。由于这是一个 EXPLICIT 模式查询,所以在所有 SELECT 语句中指定的前两个值都必须是 Tag 值和 Parent 值。<customer> 元素会得到标记号 2,而由于它是 <employee> 元素的子级,所以它具有 Parent 值 1。第一条 SELECT 语句已经指定了 emp_id、cust_id 和 region 都是属性。

      SELECT 2, 1, emp_id, cust_id, region FROM employee KEY JOIN sales_order
    3. 给查询添加 UNION ALL 以便将两条 SELECT 语句合并到一起:

      SELECT 1 AS tag, NULL AS parent, emp_id AS [employee!1!emp_id], NULL AS [customer!2!cust_id], NULL AS [customer!2!region] FROM employee UNION ALL
      SELECT 2, 1, emp_id, cust_id, region FROM employee KEY JOIN sales_order
    4. 添加 ORDER BY 子句来指定结果中行的顺序。行的顺序是最终生成的文档中使用的顺序。

      SELECT 1 AS tag, NULL AS parent, emp_id AS [employee!1!emp_id], NULL AS [customer!2!cust_id], NULL AS [customer!2!region] FROM employee UNION ALL
      SELECT 2, 1, emp_id, cust_id, region FROM employee KEY JOIN sales_order ORDER BY 3, 1 FOR XML EXPLICIT

    有关 EXPLICIT 模式的语法的信息,请参见参数

    FOR XML EXPLICIT 示例 

    下面的示例查询会检索有关雇员所下订单的信息。在本示例中,有三种元素:<emp>、<order> 和 <dept>。<emp> 元素具有 id 属性和 name 属性,<order> 元素具有 date 属性,<dept> 元素具有 name 属性。

    SELECT 1 tag, NULL parent, emp_id [emp!1!id], emp_fname [emp!1!name], NULL [order!2!date], NULL [dept!3!name] FROM employee UNION ALL
    SELECT 2, 1, emp_id, NULL, order_date, NULL FROM employee KEY JOIN sales_order UNION ALL
    SELECT 3, 1, emp_id, NULL, NULL, dept_name FROM employee e JOIN department d ON e.dept_id=d.dept_id ORDER BY 3, 1 FOR XML EXPLICIT

    利用此查询可以得到以下结果:

    <emp id="102" name="Fran"> <dept name="R &amp; D"/> </emp> <emp id="105" name="Matthew"> <dept name="R &amp; D"/> </emp>
    <emp id="129" name="Philip"> <order date="2000-07-24"/> <order date="2000-07-13"/> <order date="2000-06-24"/> <order date="2000-06-08"/> ... <dept name="Sales"/> </emp>
    <emp id="148" name="Julie"> <dept name="Finance"/> </emp> ...
    使用 element 指令 

    如果您想生成子元素而不是属性,可以给查询添加 element 指令,就像下面这样:

    SELECT 1 tag, NULL parent, emp_id [emp!1!id!element], emp_fname [emp!1!name!element], NULL [order!2!date!element], NULL [dept!3!name!element] FROM employee
    UNION ALL SELECT 2, 1, emp_id, NULL, order_date, NULL FROM employee KEY JOIN sales_order UNION ALL
    SELECT 3, 1, emp_id, NULL, NULL, dept_name FROM employee e JOIN department d ON e.dept_id=d.dept_id ORDER BY 3, 1 FOR XML EXPLICIT

    利用此查询可以得到以下结果:

    <emp> <id>102</id> <name>Fran</name> <dept> <name>R &amp; D</name> </dept> </emp>
    <emp> <id>105</id> <name>Matthew</name> <dept> <name>R &amp; D</name> </dept> </emp>
    <emp> <id>129</id> <name>Philip</name> <order> <date>2000-07-24</date> </order> <order> <date>2000-07-13</date> </order> <order> <date>2000-06-24</date> </order> ... <dept> <name>Sales</name> </dept> </emp> ...
    使用 hide 指令 

    在下面的查询中,雇员 ID 用于给结果排序,但结果中不会出现雇员 ID,因为指定了 hide 指令:
    SELECT 1 tag, NULL parent, emp_id [emp!1!id!hide], emp_fname [emp!1!name], NULL [order!2!date], NULL [dept!3!name] FROM employee UNION ALL
    SELECT 2, 1, emp_id, NULL, order_date, NULL FROM employee KEY JOIN sales_order UNION ALL
    SELECT 3, 1, emp_id, NULL, NULL, dept_name FROM employee e JOIN department d ON e.dept_id=d.dept_id ORDER BY 3, 1 FOR XML EXPLICIT

    此查询会返回以下结果:
    <emp name="Fran"> <dept name="R &amp; D"/> </emp> <emp name="Matthew"> <dept name="R &amp; D"/> </emp>
    <emp name="Philip"> <order date="2000-07-24"/> <order date="2000-07-13"/> <order date="2000-06-24"/> <order date="2000-06-08"/> ... <dept name="Sales"/> </emp>
    <emp name="Julie"> <dept name="Finance"/> </emp> ...
    使用 xml 指令 

    缺省情况下,当 FOR XML EXPLICIT 查询的结果包含不是有效 XML 字符的字符时,无效字符会被转义(有关信息请参见无效的列名),除非该列是 XML 类型。例如,下面的查询会生成包含"&"符号的 XML:
    SELECT 1 AS tag, NULL AS parent, id AS [customer!1!id!element], company_name AS [customer!1!company_name] FROM customer WHERE id = '115' FOR XML EXPLICIT

    在此查询生成的结果中,"&"符号会被转义,因为该列不是 XML 类型:
    <customer company_name="Sterling &amp; Co."> <id>115</id> </customer>

    xml 指令表明列值在插入生成的 XML 中时不带引号。如果您用 xml 指令执行与上面的查询相同的查询:
    SELECT 1 AS tag, NULL AS parent, id AS [customer!1!id!element], company_name AS [customer!1!company_name!xml] FROM customer WHERE id = '115' FOR XML EXPLICIT

    结果中的"&"号就不会带有引号:
    <customer> <id>115</id> <company_name>Sterling & Co.</company_name> </customer>

    请注意,此 XML 并非结构完好,因为它包含"&"号,而这在 XML 中是一个特殊字符。当查询生成了 XML 时,您有责任确保该 XML 结构完好并且有效,因为 Adaptive Server Anywhere 不会检查所生成的 XML 是否结构完好或有效。
    当您指定 xml 指令时,AttributeName 字段会被忽略,并且会生成元素而不是属性。
    使用 cdata 指令 

    下面的查询使用 cdata 指令在 CDATA 节中返回客户名称:
    SELECT 1 AS tag, NULL AS parent, id AS [product!1!id], description AS [product!1!cdata] FROM product FOR XML EXPLICIT

    此查询生成的结果会在 CDATA 节中列出对每种产品的说明。CDATA 节中包含的数据不带引号:
    <product id="300"> <![CDATA[Tank Top]]> </product> <product id="301"> <![CDATA[V-neck]]> </product>
    <product id="302"> <![CDATA[Crew Neck]]> </product> <product id="400"> <![CDATA[Cotton Cap]]> </product> ...
    使用 hide 指令 

    在下面的查询中,雇员 ID 用于给结果排序,但结果中不会出现雇员 ID,因为指定了 hide 指令:
    SELECT 1 tag, NULL parent, emp_id [emp!1!id!hide], emp_fname [emp!1!name], NULL [order!2!date], NULL [dept!3!name] FROM employee UNION ALL
    SELECT 2, 1, emp_id, NULL, order_date, NULL FROM employee KEY JOIN sales_order UNION ALL
    SELECT 3, 1, emp_id, NULL, NULL, dept_name FROM employee e JOIN department d ON e.dept_id=d.dept_id ORDER BY 3, 1 FOR XML EXPLICIT

    此查询会返回以下结果:
    <emp name="Fran"> <dept name="R &amp; D"/> </emp> <emp name="Matthew"> <dept name="R &amp; D"/> </emp>
    <emp name="Philip"> <order date="2000-07-24"/> <order date="2000-07-13"/> <order date="2000-06-24"/> <order date="2000-06-08"/> ... <dept name="Sales"/> </emp>
    <emp name="Julie"> <dept name="Finance"/> </emp> ...
    使用 xml 指令 

    缺省情况下,当 FOR XML EXPLICIT 查询的结果包含不是有效 XML 字符的字符时,无效字符会被转义(有关信息请参见无效的列名),除非该列是 XML 类型。例如,下面的查询会生成包含"&"符号的 XML:
    SELECT 1 AS tag, NULL AS parent, id AS [customer!1!id!element], company_name AS [customer!1!company_name] FROM customer WHERE id = '115' FOR XML EXPLICIT

    在此查询生成的结果中,"&"符号会被转义,因为该列不是 XML 类型:
    <customer company_name="Sterling &amp; Co."> <id>115</id> </customer>

    xml 指令表明列值在插入生成的 XML 中时不带引号。如果您用 xml 指令执行与上面的查询相同的查询:
    SELECT 1 AS tag, NULL AS parent, id AS [customer!1!id!element], company_name AS [customer!1!company_name!xml] FROM customer WHERE id = '115' FOR XML EXPLICIT

    结果中的"&"号就不会带有引号:
    <customer> <id>115</id> <company_name>Sterling & Co.</company_name> </customer>

    请注意,此 XML 并非结构完好,因为它包含"&"号,而这在 XML 中是一个特殊字符。当查询生成了 XML 时,您有责任确保该 XML 结构完好并且有效,因为 Adaptive Server Anywhere 不会检查所生成的 XML 是否结构完好或有效。
    当您指定 xml 指令时,AttributeName 字段会被忽略,并且会生成元素而不是属性。
    使用 cdate 指令 

    下面的查询使用 cdata 指令在 CDATA 节中返回客户名称:
    SELECT 1 AS tag, NULL AS parent, id AS [product!1!id], description AS [product!1!cdata] FROM product FOR XML EXPLICIT

    此查询生成的结果会在 CDATA 节中列出对每种产品的说明。CDATA 节中包含的数据不带引号:
    <product id="300"> <![CDATA[Tank Top]]> </product> <product id="301"> <![CDATA[V-neck]]> </product>
    <product id="302"> <![CDATA[Crew Neck]]> </product> <product id="400"> <![CDATA[Cotton Cap]]> </product> ...
  • 相关阅读:
    物联网市场碎片化严重 物联网网关设计挑战重重
    物联网市场碎片化严重 物联网网关设计挑战重重
    物联网市场碎片化严重 物联网网关设计挑战重重
    越做越大的行李寄存生意,老板竟是3个95后
    互联网人失业理由排行榜,每一个都戳破职场真相
    读小说赚钱吗?这个年入百万
    BI驾驶舱的必备知识
    2019开源BI软件排行榜
    主流的开源bi工具
    企业为什么需要BI决策系统?
  • 原文地址:https://www.cnblogs.com/gongyu/p/3850157.html
Copyright © 2011-2022 走看看