2015-04-07 40 views
1

我有以下存储过程:拆分逗号分隔VARCHAR参数成临时表

CREATE PROCEDURE myProc 
    @nameList varchar(500) 
AS 
BEGIN 
    create table #names (Name varchar(20)) 

    -- split @nameList up into #names table 
END 
GO 

@nameList将基本上是这样的:

'John, Samantha, Bob, Tom' 

回答

4

使用转换为XMLcross apply

DECLARE @str varchar(50) 
    SET @str='John, Samantha, Bob, Tom' 

    SELECT names = y.i.value('(./text())[1]', 'nvarchar(1000)')    
    FROM 
    ( 
    SELECT 
     n = CONVERT(XML, '<i>' 
      + REPLACE(@str, ',' , '</i><i>') 
      + '</i>') 
) AS a 
    CROSS APPLY n.nodes('i') AS y(i) 

OUT PUT:

names 
----- 
John 
Samantha 
Bob 
Tom 

编辑:它不需要临时表的proc中,因此PROC将是:

CREATE PROCEDURE myProc 

    (@nameList varchar(500)) 

AS 
BEGIN 

     SELECT names = y.i.value('(./text())[1]', 'nvarchar(1000)')    
     FROM 
     ( 
     SELECT 
      n = CONVERT(XML, '<i>' 
       + REPLACE(@nameList, ',' , '</i><i>') 
       + '</i>') 
    ) AS a 
     CROSS APPLY n.nodes('i') AS y(i) 
END 

,但如果你想将它插入到一个临时表,下面是一个示例:

create table #names 
    (
     Name varchar(20) 
    ) 

    DECLARE @str varchar(50) 
    SET @str='John, Samantha, Bob, Tom' 

    insert into #names 
    SELECT names = y.i.value('(./text())[1]', 'nvarchar(1000)')    
    FROM 
    ( 
    SELECT 
     n = CONVERT(XML, '<i>' 
      + REPLACE(@str, ',' , '</i><i>') 
      + '</i>') 
) AS a 
    CROSS APPLY n.nodes('i') AS y(i) 

    select * from #names 
    drop table #names 

编辑2:输入字符串可以包含一些特殊恰拉cters喜欢'<' , '>' , etc它不是标准的名字,但如果给定的字符串包含他们,你可以通过使用replace功能删除它们:replace(@str,'<','')

+0

这是一些好看的SQL!非常感谢:) – Tiwaz89

+0

虽然,不应该说某处“select INTO #names”...? – Tiwaz89

+0

不客气,只是让我把它编辑成你的程序格式 – jfun

0

您可以创建函数并调用从徘徊无论你想拆分此功能: -

create FUNCTION [dbo].[SplitStrings](@nameList varchar(MAX), @Delimiter char(1))  
returns @temptable TABLE (names varchar(MAX))  
as  
begin  
    declare @id int  
    declare @x varchar(8000)  

    select @id = 1  
     if len(@nameList)<1 or @nameList is null return  

    while @id!= 0  
    begin  
     set @id = charindex(@Delimiter,@nameList)  
     if @id!=0  
      set @x = left(@nameList,@id - 1)  
     else  
      set @x = @nameList 

     if(len(@x)>0) 
      insert into @temptable(names) values(@x)  

     set @String = right(@nameList,len(@nameList) - @id)  
     if len(@nameList) = 0 break  
    end 
return 
end; 
1

随着递归CTE:

DECLARE @nameList NVARCHAR(MAX) = 'John, Samantha, Bob, Tom' 
SET @nameList = @nameList + ','; 

WITH cte 
      AS (SELECT SUBSTRING(@nameList, 0, CHARINDEX(',', @nameList)) AS n , 
         CHARINDEX(',', @nameList) AS i 
       UNION ALL 
       SELECT SUBSTRING(@nameList, i + 2,CHARINDEX(',', @nameList, i + 2) - i - 2) , 
         CHARINDEX(',', @nameList, i + 2) 
       FROM  cte 
       WHERE CHARINDEX(',', @nameList, i + 2) > 0 
      ) 
    SELECT n FROM cte 

输出:

n 
John 
Samantha 
Bob 
Tom 
0
CREATE FUNCTION [dbo].[Split] 
(
    @RowData nvarchar(MAX), 
    @SplitOn nvarchar(5) 
) 
RETURNS @RtnValue table 
(
    Id int identity(1,1), 
    Data nvarchar(100) 
) 
AS 
BEGIN 
    Declare @Cnt int 
    Set @Cnt = 1 

    While (Charindex(@SplitOn,@RowData)>0) 
    Begin 
     Insert Into @RtnValue (data) 
     Select 
      Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1))) 

     Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData)) 
     Set @Cnt = @Cnt + 1 
    End 

    Insert Into @RtnValue (data) 
    Select Data = ltrim(rtrim(@RowData)) 

    Return 
END