摘要:sql中的for xml语法为表转化为xml提供了很好的支持,固然使用一样的程序语言也可以达到一样的效果,可是有了for xml将使得这一切更加的方便。sql
Select 的查询结果会做为行集返回,可是你一样能够在sql中指定for xml子句使得查询做为xml来检索。在for xml子句中,能够指定如下模式之一:RAW 、AUTO、EXPLICIT和PATH。this
RAW模式返回行为元素,每一列的值做为元素的属性;AUTO模式返回表名为节点的元素,每一列的属性做为属性输出;EXPLICIT模式经过SELECT语法定义输出XML结构;PATH模式中列名或列别名做为XPATH表达式来处理。spa
下面是四种方式输出的效果code
RAW模式xml
SELECT TOP 5 ProductName,UnitPrice FROM dbo.Products FOR XML RAW
查询结果blog
<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模式element
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,其值为:1024八、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