SQL FOR XML


摘要: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之后查詢到的數據時如下形式:

 sqlFORXML

按照上面的規則不難看出,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

OK,今天就到這里吧,祝大家元旦快樂!

知識共享許可協議 作品采用知識共享署名 2.5 中國大陸許可協議進行許可,歡迎轉載,演繹或用於商業目的。但轉載請注明來自崔江濤(KenshinCui),並包含相關鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM