FOR XML PATH ,其實它就是將查詢結果集以XML形式展現,將多行的結果,展示在同一行。
下面我們來寫一個例子:
假設我們有個工作流程表:
CREATE TABLE [dbo].[Workflow_Action]( [WorkflowSchema] [nvarchar](128) NULL, [ActionSchema] [nvarchar](128) NULL, [ActionName] [nvarchar](64) NULL ) INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('material-price','confirm','審核通過') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('material-price','reject','審核駁回') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('material-price','executing','執行價格') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('material-price','non-executing','不執行價格') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('oa-meeting-apply','confirm','審核通過') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('oa-meeting-apply','reject','審核駁回') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('oa-officialSeal-apply','confirm','審核通過') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('oa-officialSeal-apply','reject','審核駁回') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('oa-officialSeal-apply','returned','歸還公章') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','commit','提交審核') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','reject','采購駁回') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','confirm','審核通過') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','order','采購下單') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','recommit','重新提交審核') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','part-consignment','部分收貨') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase','consignment','完成收貨') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase-request','commit','提交審核') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase-request','confirm','審核通過') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase-request','reject','申請駁回') INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES ('purchase-request','recommit','重新提交審核')

一、簡單介紹
接下來,我們用這個方法查詢這個表的數據。
select * from [dbo].[Workflow_Action] for xml path
它可以將查詢結果轉換為一段XML格式的代碼
--for xml path 后面可以寫東西,for xml path(Schema),這樣寫的話,可以將節點<row>變成<Schema> select WorkflowSchema as WS,ActionSchema as SC,ActionName as AN from [dbo].[Workflow_Action] for xml path('Schema')
--我們還可以單獨輸出某一個字段的值 SELECT '[ '+ActionName+' ]' FROM [dbo].[Workflow_Action] FOR XML PATH('')
二、實際應用
--我們看看一個操作對應的而多格流程 --一共是兩層,里面一層查出單獨的ActionName,拼成一行,然后使用where條件連接外層 SELECT WorkflowSchema, (SELECT ActionName+',' FROM [dbo].[Workflow_Action] WHERE WorkflowSchema=A.WorkflowSchema --必須加的條件 FOR XML PATH('')) AS ActionList FROM [dbo].[Workflow_Action] A GROUP BY WorkflowSchema
--where 連接條件必須要,如果去掉,就會查出所有的ActionName,如同上面示例一樣
--現在我們優化一下格式,會發現最后多了一個‘,’符號,用LEFT函數去掉他,繼續在外面接一層查詢 select B.WorkflowSchema,
LEFT(B.ActionList,LEN(B.ActionList)-1) as ActionList
from ( SELECT WorkflowSchema, (SELECT ActionName+',' FROM [dbo].[Workflow_Action] WHERE WorkflowSchema=A.WorkflowSchema FOR XML PATH('')) AS ActionList FROM [dbo].[Workflow_Action] A GROUP BY WorkflowSchema) as B
接下來,我們再講一個其他的函數,實現同樣的效果,STUFF函數。
sql stuff函數用於刪除指定長度的字符,並可以在制定的起點處插入另一組字符。sql stuff函數中如果開始位置或長度值是負數,或者如果開始位置大於第一個字符串的長度,將返回空字符串。如果要刪除的長度大於第一個字符串的長度,將刪除到第一個字符串中的第一個字符。
一、作用
刪除指定長度的字符,並在指定的起點處插入另一組字符。
二、語法
STUFF ( character_expression , start , length ,character_expression )
參數
character_expression 一個字符數據表達式。character_expression 可以是常量、變量,也可以是字符列或二進制數據列。
start 一個整數值,指定刪除和插入的開始位置。如果 start 或 length 為負,則返回空字符串。如果 start 比第一個 character_expression 長,則返回空字符串。start 可以是 bigint 類型。
length 一個整數,指定要刪除的字符數。如果 length 比第一個 character_expression 長,則最多刪除到最后一個 character_expression 中的最后一個字符。length 可以是 bigint 類型。
返回類型
如果 character_expression 是受支持的字符數據類型,則返回字符數據。如果 character_expression 是一個受支持的 binary 數據類型,則返回二進制數據。
三、備注
1、如果開始位置或長度值是負數,或者如果開始位置大於第一個字符串的長度,將返回空字符串。如果要刪除的長度大於第一個字符串的長度,將刪除到第一個字符串中的第一個字符。
2、如果結果值大於返回類型支持的最大值,則產生錯誤。
四、sql stuff函數
--實例一 select STUFF('abcdefg',1,0,'1234') --結果為'1234abcdefg' select STUFF('abcdefg',1,1,'1234') --結果為'1234bcdefg' select STUFF('abcdefg',2,1,'1234') --結果為'a1234cdefg' select STUFF('abcdefg',2,2,'1234') --結果為'a1234defg'
--實例二、SQL 將列轉成字符串並用逗號分隔 --同樣的,我們也用到了for xml path這個方法 SELECT STUFF((SELECT ',' + ActionName FROM [dbo].[Workflow_Action] FOR XML PATH('')),1,1,'') AS WA
--實例三、最后我們實現,上面for xml path的功能 --先查出兩個字段,然后對ActionName這個字段進行轉化,where條件記得加上,不加就會顯示出所有的ActionName select WorkflowSchema, ActionName=(STUFF((select ',' + ActionName from [dbo].[Workflow_Action] a where a.WorkflowSchema=b.WorkflowSchema for xml path('')),1,1,'')) --where條件必須加上 from [dbo].[Workflow_Action] b group by WorkflowSchema
對比以上兩種做法,可以自行比較哪種方式更加簡便。


