摘要:sql中的for xml语法为表转化为xml提供了很好的支持,当然使用同样的程序语言也能够达到同样的效果,但是有了for xml将使得这一切更加的方便。

主要内容:

Select 的查询结果会作为行集返回,但是你同样可以在sql中指定for xml子句使得查询作为xml来检索。在for xml子句中,可以指定以下模式之一:RAW 、AUTO、EXPLICIT和PATH。

RAW模式返回行为元素,每一列的值作为元素的属性;AUTO模式返回表名为节点的元素,每一列的属性作为属性输出;EXPLICIT模式通过SELECT语法定义输出XML结构;PATH模式中列名或列别名作为XPATH表达式来处理。

下面是四种方式输出的效果

RAW模式

SELECT TOP 5 ProductName,UnitPrice FROM dbo.Products FOR XML RAW

查询结果

<row ProductName="Chai" UnitPrice="18.0000" />
<row ProductName="Chang" UnitPrice="19.0000" />
<row ProductName="Aniseed Syrup" UnitPrice="10.0000" />
<row ProductName="Chef Anton's Cajun Seasoning" UnitPrice="22.0000" />
<row ProductName="Chef Anton's Gumbo Mix" UnitPrice="21.3500" />

AUTO模式

SELECT TOP 5 ProductName,UnitPrice FROM dbo.Products FOR XML AUTO

查询结果

<dbo.Products ProductName="Chai" UnitPrice="18.0000" />
<dbo.Products ProductName="Chang" UnitPrice="19.0000" />
<dbo.Products ProductName="Aniseed Syrup" UnitPrice="10.0000" />
<dbo.Products ProductName="Chef Anton's Cajun Seasoning" UnitPrice="22.0000" />
<dbo.Products ProductName="Chef Anton's Gumbo Mix" UnitPrice="21.3500" />

EXPLICIT模式

SELECT TOP 5 1 AS Tag,0 AS Parent, OrderID AS [Order!1!ID],OrderDate AS [Order!1!Date],CustomerID AS [Order!1!Customer],NULL AS [OrderDetail!2!ProductID],NULL AS [OrderDetail!2!UnitPrice],NULL AS [OrderDetail!2!Quantity] FROM dbo.Orders WHERE dbo.Orders.OrderID='10248'
UNION ALL
SELECT TOP 5 2 AS Tag,1 AS Parent, NULL,NULL ,NULL,ProductID,UnitPrice,Quantity FROM dbo.[Order Details] WHERE OrderID='10248'
FOR XML EXPLICIT

查询结果

<Order ID="10248" Date="1996-07-04T00:00:00" Customer="VINET">
<OrderDetail ProductID="11" UnitPrice="14.0000" Quantity="12" />
<OrderDetail ProductID="42" UnitPrice="9.8000" Quantity="10" />
<OrderDetail ProductID="72" UnitPrice="34.8000" Quantity="5" />
</Order>

PATH模式

SELECT TOP 5 ProductName AS Name, UnitPrice AS Price FROM dbo.Products FOR XML PATH('Cmj')

查询结果

<Cmj>
<Name>Chai</Name>
<Price>18.0000</Price>
</Cmj>
<Cmj>
<Name>Chang</Name>
<Price>19.0000</Price>
</Cmj>
<Cmj>
<Name>Aniseed Syrup</Name>
<Price>10.0000</Price>
</Cmj>
<Cmj>
<Name>Chef Anton's Cajun Seasoning</Name>
<Price>22.0000</Price>
</Cmj>
<Cmj>
<Name>Chef Anton's Gumbo Mix</Name>
<Price>21.3500</Price>
</Cmj>

RAW模式和AUTO模式相对比较简单,灵活性当然也是比较差的。EXPLICIT模式会将查询执行生成的行集转换为XML文档,也就是说结构可以自定义,当然这必须符合一定的格式。就拿上面的语句来说:

Tag指定生成节点的嵌套级别,列名必须为"Tag"例如上面的级别为1。

Parent指定当前Tag的父级层次,列名必须为"Parent",NULL表示顶级。

其他列名,例如[Order!1!ID]分别代表元素名称、Tag标记(也就是层级)、属性名称。例如上面的这一列就代表会在第一级节点中生成一个节点名称为Order的节点并且有一个属性ID。

此外还需要指出的是这个列名还有一个可选部分,完整的形式是[ElementName!TagNumber!AttributeName!Directive],最后一部分Directive是可选的,如果不指定的话默认作为ElementName中的属性名称;当然如果制定了xml、cdata或者element那么它将作为ElementName的一个子元素而不是属性。并且指定了此选项之后AttributeName可以为空。

上面的例子中如果去掉For XML EXPLICIT之后查询到的数据时如下形式:

按照上面的规则不难看出,FOR XML EXPLICIT会按照顺序生成xml:

第一次执行(第一行数据)时tag为1,parent为0,则此时会按照列名创建一个Order节点,并依次创建三个属性:ID、Date和Customer,其值为:10248、1996-07-04 00:00:00.000、VINET。此时不会生成ProductID属性,因为它的Tag为2,需要在第二级节点中创建,其他另个属性也是如此。

第二次执行(第二行数据)时Tag为2,Parent为1,也就是要在Tag为1的节点中创建一个2级节点。然后根据查找列名中Tag为2的列,依次创建ProductID、UnitPrice、Quantity属性,并赋值。

第三次、第四次同第二次执行类似,不同的只是数据而已。

PATH模式应该说是使用率相当高的,原因比较简单,它的使用既简单又灵活。在PATH模式中,节点名称可以使列名也可以通过别名指定又或者根本不指定,不指定的情况下就只显示节点内数据;根节点可以指定也可以不指定,不指定情况下默认为"row",并且根节点指定为""的情况下可以完全取消根节点的显示。有了这一属性就可以使用PATH模式完成很多有用的操作。

没有指定根节点时:

SELECT TOP 5 ProductName FROM dbo.Products FOR XML PATH
<row>
<Name>Chai</Name>
<Price>18.0000</Price>
</row>
<row>
<Name>Chang</Name>
<Price>19.0000</Price>
</row>
<row>
<Name>Aniseed Syrup</Name>
<Price>10.0000</Price>
</row>
<row>
<Name>Chef Anton's Cajun Seasoning</Name>
<Price>22.0000</Price>
</row>
<row>
<Name>Chef Anton's Gumbo Mix</Name>
<Price>21.3500</Price>
</row>

去掉根节点名称:

SELECT TOP 5 ProductName FROM dbo.Products FOR XML PATH('')
<ProductName>Alice Mutton</ProductName>
<ProductName>Aniseed Syrup</ProductName>
<ProductName>Boston Crab Meat</ProductName>
<ProductName>Camembert Pierrot</ProductName>
<ProductName>Carnarvon Tigers</ProductName>

去掉根节点和子节点名称:

SELECT TOP 5 ProductName+'' FROM dbo.Products FOR XML PATH('')
Alice MuttonAniseed SyrupBoston Crab MeatCamembert PierrotCarnarvon Tigers

可以发现去掉节点名称之后for xml path起到了字符串连接的作用,这样一来就可以利用这一特性完成字符串拼接,例如下面的语句就能完成可以将五种产品用","进行分割的功能:

SELECT LEFT(ProductNames,(LEN(ProductNames)-1)) FROM(
SELECT
(SELECT TOP 5 ProductName+',' FROM dbo.Products FOR XML PATH('')) AS ProductNames
) AS T

原文地址:崔江涛(KenshinCui)

(Sql Server)SQL FOR XML的更多相关文章

  1. (Sql Server)SQL FOR XML PATH

    FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作.那么以一个实例为主 ...

  2. 大哥带的MSsql注入(SQL Server)--预习

    ①判断数据库类型and exists (select * from sysobjects)--返回正常为mssql(也名sql server)and exists (select count(*) f ...

  3. (4.22)sql server视图/索引视图概念

    (4.22)sql server视图 关键词:sql server视图.索引视图 SQL Server视图是由SQL语句组成的逻辑数据库对象.它也可以称为由SQL语句组成的虚拟表,该SQL语句可能包含 ...

  4. (4.20)sql server性能指标、性能计数器

    (4.20)sql server性能指标.性能计数器 常规计数器 收集操作系统服务器的服务器性能信息,包括Processor.磁盘.网络.内存 Processor 处理器 1.1 % Processo ...

  5. (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务)

    (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务) 1.概念:隐式事务,显式事务,自动提交事务 2.操作:如何设置事务模式 3.存储过程中的事务 XACT_ABORT 1 ...

  6. (4.1)SQL Server Browser 与动态端口

    转自:http://blog.51cto.com/jimshu/1120295 一.启用TCP端口 1.启用TCP/IP协议 打开SSCM(SQL Server Configuration Manag ...

  7. (4.16)sql server迁移DB文件(同一DB内)

    SQL Server 修改数据库物理文件存在位置 关键词:迁移文件,迁移temp库(这怎么迁移呢,用方法2即可,需要重启实例) 三种均需要离线: 一共分为(1)脱机迁移和(2)在线迁移. (1)迁移方 ...

  8. 开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs

    原文:开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs 快速入门:使用 Docker ...

  9. 批处理创建数据库(Sql Server)

    ylbtech-Miscellaneos:批处理创建数据库(Sql Server) 1.A,资源(Resource) - 创建数据返回顶部 1.A.1,InstallDatabases.cmd - 编 ...

随机推荐

  1. checkBox判断是否选中的方法

    这里可以分为两种情况:JQuery对象和DOM对象: 通常我们用JQuery判断元素的属性的时候喜欢用 attr("attrName"); 但是尝试过的同学可能都知道,这种方法判断 ...

  2. easyui中在formatter: function (value, row,index) {中添加删除方法

    { field : 'abj', title : '操作', align : 'center', resizable:false, width:'10%', formatter: function ( ...

  3. django-mdeditor支持七牛云存储图片

    由于django-mdeditor官方插件没有支持第三方存储,所以,我们只能进行修改源码的方式实现了. 本次改写即使替换了其文件,不使用七牛云也是无关紧要的,因为在存储时,去settings.py中判 ...

  4. 关于STM32的CAN的过滤器

    关于STM32的CAN的过滤器STM32普通型芯片的CAN有14组过滤器组,互联型有28组过滤器组.一般我们用的都是普通型的,所以在本文中可以说STM32有14组过滤器组.根据配置,每1组过滤器组可以 ...

  5. [C#] 使用 Excel 和 Math.Net 进行曲线拟合和数据预测

    以前在工作中遇到了一个数据错误的问题,顺便写下 用 Math.Net 解决的思路. 1. 错误的数据 上图是同一组探测器在同一天采集到的 19 次数据,总体来说重复性不错,但很明显最后 8 个探测器出 ...

  6. CentOS8_在线安装_网络源_网络镜像源填写格式_以及其他笔记

    CentOS8_在线安装_网络源_网络镜像源填写格式_以及其他笔记 转载注明来源: 本文链接 来自osnosn的博客,写于 2020-10-1. 参考: Centos8.0.1905 在线安装源选择 ...

  7. APACHE如何里一个站点绑定多个域名?用ServerAlias 转

    APACHE2如何里一个站点绑定多个域名?用ServerAlias以前很笨,要使多个域名指向同一站点总是这样写:<VirtualHost *:80>ServerAdmin i@kuigg. ...

  8. JDK动态代理案例与原理分析

    一.JDK动态代理实现案例 Person接口 package com.zhoucong.proxy.jdk; public interface Person { // 寻找真爱 void findlo ...

  9. Solon rpc 之 SocketD 协议 - 消息订阅模式

    Solon rpc 之 SocketD 协议系列 Solon rpc 之 SocketD 协议 - 概述 Solon rpc 之 SocketD 协议 - 消息上报模式 Solon rpc 之 Soc ...

  10. tp where使用数组条件,如何设置or,and

    1 //where条件数组拼接 2 $where['status'] = 1; 3 $maps['id'] = ['in', implode(',', $r_ids)]; 4 $maps['uid'] ...