SQL Server FOR XML PATH 和 STUFF函數的用法

   FOR XML PATH ,其實它就是將查詢結果集以XML形式展示,將多行的結果,展現在同一行。sql

    下面咱們來寫一個例子:express

        假設咱們有個工做流程表:app

    
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','從新提交審覈')
數據表和數據

    

 

    1、簡單介紹ide

      接下來,咱們用這個方法查詢這個表的數據。函數

   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('')
    

 

    2、實際應用  優化

   --咱們看看一個操做對應的而多格流程    --一共是兩層,裏面一層查出單獨的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函數。spa

    sql stuff函數用於刪除指定長度的字符,並能夠在制定的起點處插入另外一組字符。sql stuff函數中若是開始位置或長度值是負數,或者若是開始位置大於第一個字符串的長度,將返回空字符串。若是要刪除的長度大於第一個字符串的長度,將刪除到第一個字符串中的第一個字符。3d

    1、做用code

      刪除指定長度的字符,並在指定的起點處插入另外一組字符。xml

    2、語法

      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 數據類型,則返回二進制數據。

    3、備註

      一、若是開始位置或長度值是負數,或者若是開始位置大於第一個字符串的長度,將返回空字符串。若是要刪除的長度大於第一個字符串的長度,將刪除到第一個字符串中的第一個字符。

      二、若是結果值大於返回類型支持的最大值,則產生錯誤。

    4、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'
    --實例2、SQL 將列轉成字符串並用逗號分隔     --一樣的,咱們也用到了for xml path這個方法
    SELECT STUFF((SELECT ',' + ActionName FROM [dbo].[Workflow_Action] FOR XML PATH('')),1,1,'') AS WA
     
    --實例3、最後咱們實現,上面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
     

 

    對比以上兩種作法,能夠自行比較哪一種方式更加簡便。

相關文章
相關標籤/搜索