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


   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
     

 

    對比以上兩種做法,可以自行比較哪種方式更加簡便。


免責聲明!

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



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