VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

SELECT FOR XML

功能描述

Vastbase在SQL Server兼容模式下,支持SELECT查询的FOR XML子句,即以XML字符串的形式显示查询结果集。

  • FOR XML子句可用于顶层查询和子查询。
  • 顶层FOR XML子句只能在SELECT语句中使用。
  • 在子查询中,FOR XML可用于 INSERT、UPDATE 和 DELETE语句。
  • FOR XML可以在赋值语句中使用。

注意事项

  • 该功能仅在数据库兼容模式为SQL Server时支持(即数据库实例初始化时指定DBCOMPATIBILITY='MSSQL')。

  • Vastbase仅支持本章节中介绍的列的XML映射规则,其余未提及的各映射特性暂不支持。

  • 如果FOR XML查询的列值为空,这意味着在返回结果中这些元素不具有值,详见示例2

语法格式

SELECT ... FOR XML [ PATH [ ('Element_Name') ] ];

参数说明

  • PATH

    FOR XML可以通过指定关键词来控制XML的生成模式,当前Vastbase仅支持PATH模式,不支持其它模式(AUTO,RAW,EXPLICIT)。

    PATH模式是一种简单的匹配方式,它将表中的列或者别名做为 XPATH表达式来进行处理。这些表达式明确了如何将值映射到 XML。每一个XPATH表达式都是一个相对 XPATH,从中可以得到相对于行元素而生成的节点名称与层次结构。

    映射规则一节中介绍了如何在各种条件下映射行集中的列,并提供了相关示例。

  • Element_Name

    支持为行元素指定新的名称Element_Name以覆盖默认的<row>,详见支持指定包装元素名称

映射规则

没有名称的列

任何没有名称的列都将成为内联列。 例如,未指定列别名的计算列或嵌套标量查询将生成不带任何名称的列。 如果该列属于XML类型,则将插入该数据类型实例的内容。 否则,列内容将作为文本节点插入。

SELECT 2 + 2 FOR XML PATH;

默认情况下,对于行集中的每一行,生成的XML中都会包含一个<row>元素。上述语句的返回结果如下:

 XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------
 <row>4</row>
(1 row)

下面这个示例用到了示例1中创建的测试表PRODUCTION,如下语句在FOR XML查询时返回了多个列。

SELECT ProductionID, ProductionName 
FROM PRODUCTION WHERE ProductionID=1
FOR XML PATH;

返回结果如下:

                     XML_F52E2B61-18A1-11d1-B105-00805F49916B
----------------------------------------------------------------------------------
 <row><productionid>1</productionid><productionname>cookie</productionname></row>
(1 row)

具有名称的列

下面是一些特定条件,在这些条件下具有名称的行集列将映射(区分大小写)到生成的 XML:

  • 不支持列名包含斜杠(/)标记。
  • 不支持层级。
  • 不支持列名包含特殊字符的列,包括:text(),comment(),node(),data(),*

列名以@符号开头

如果列名称以@符号开头,并且不包含斜杠标记(/),则会创建具有相应列值的元素的属性<row>。

例如,以下查询从PRODUCTION表(表的创建参考示例1)返回一个双列 @Pdt, ProductionName 行集。 在生成的 XML 中,将Pdt属性添加到相应的 <row> 元素,并用ProductionID为其赋值。

SELECT ProductionID as "@Pdt",ProductionName
FROM PRODUCTION WHERE Price = '25'
FOR XML PATH;

返回结果如下:

          XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------------------------
 <row Pdt="1"><productionname>cookie</productionname></row>
(1 row)

属性必须位于同一级别的任何其他节点类型(例如元素节点和文本节点)之前。 以下查询将返回一个错误:

SELECT ProductionName, ProductionID as "@Pdt" 
FROM PRODUCTION WHERE Price = '25'
FOR XML PATH;

列名不以@符号开头

如果列名称不以 at 符号开头 (@) ,不是 XPath 节点测试之一,并且不包含斜杠标记 (/) ,则默认创建作为行元素子元素的 XML 元素 row 。

SELECT 2 + 2 as result for xml PATH;

上述查询指定了列名为result。 因此,会向<row>元素添加<result>子元素,返回结果如下:

 XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------
 <row><result>4</result></row>
(1 row)

支持根元素

通过在ROOT查询中指定FOR XML选项,可以为生成的XML 请求一个顶层元素,如该查询中所示。

如下查询为FOR XML生成的XML指定了根元素(PRODUCTION表的创建参考示例1):

SELECT ProductionID, ProductionName 
FROM PRODUCTION WHERE Price = '25'
FOR XML PATH, ROOT('MyRoot');

为ROOT指令指定的参数提供了根元素名称,返回结果如下:


                             XML_F52E2B61-18A1-11d1-B105-00805F49916B
---------------------------------------------------------------------------------------------------
 <MyRoot><row><productionid>1</productionid><productionname>cookie</productionname></row></MyRoot>
(1 row)

支持指定包装元素名称

可以选择指定行元素名称以覆盖默认<row>。 例如,以下查询将返回行集中每一行的元素。

SELECT ProductionID, ProductionName 
FROM PRODUCTION WHERE ProductionID=1
FOR XML PATH('result');

返回结果如下,生成的XML包含指定的行元素名称:

                        XML_F52E2B61-18A1-11d1-B105-00805F49916B
----------------------------------------------------------------------------------------
 <result><productionid>1</productionid><productionname>cookie</productionname></result>
(1 row)

如果指定零长度字符串,则不会生成包装元素:

SELECT ProductionID, ProductionName 
FROM PRODUCTION WHERE ProductionID=1
FOR XML PATH('');

返回结果如下:

               XML_F52E2B61-18A1-11d1-B105-00805F49916B
-----------------------------------------------------------------------
 <productionid>1</productionid><productionname>cookie</productionname>
(1 row)

示例

示例1: 创建测试表PRODUCTION并插入数据。

此处仅列出表的创建语句,关于FOR XML示例及分析请参考映射规则小节中的各小标题。

CREATE TABLE PRODUCTION
(ProductionID int PRIMARY KEY NOT NULL, ProductionName varchar(25) NOT NULL, Price money , Description text);
insert into PRODUCTION values(1,'cookie',25,'food');
insert into PRODUCTION values(2,'milk',60,'drink');

示例2: 没有名称的列,FOR XML查询的列值为空。

1、创建测试表,不插入数据。

create table table_1160902 (col1 int,col2 varchar(10));

2、FOR XML查询的列值为空。

select col1,col2 from table_1160902 for xml path;

返回结果如下:

 XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------

(1 row)

3、为col1字段插入数值,此时col2字段仍为空。

insert into table_1160902 values (1);

4、执行FOR XML查询。

select col1,col2 from table_1160902 for xml path;

返回结果如下,

 XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------
 <row><col1>1</col1><col2/></row>
 (1 row)

示例3: 在子查询中使用FOR XML查询。

1、创建示例1中的测试表PRODUCTION,查看测试表数据。

select * from production;

返回结果如下:

 productionid | productionname | price  | description
--------------+----------------+--------+-------------
            1 | cookie         | $25.00 | food
            2 | milk           | $60.00 | drink
(2 rows)

2、在UPDATE的子查询中使用FOR XML查询:利用子查询找到商品ID(ProductionID)为1的行,将其商品描述(Description)赋值给商品ID(ProductionID)为2的行。在得到子查询的查询结果时将其返回内容转换为XML的形式。

UPDATE PRODUCTION SET Description =(SELECT Description FROM PRODUCTION WHERE ProductionID = '1' FOR XML PATH ) WHERE ProductionID ='2';

3、查看PRODUCTION表的当前数据。

select * from production;

返回结果如下:

 productionid | productionname | price  |                description
--------------+----------------+--------+--------------------------------------------
            1 | cookie         | $25.00 | food
            2 | milk           | $60.00 | <row><description>food</description></row>
(2 rows)