2013-10-06 60 views
3

我有以下Split功能,SQL拆分功能和订购问题?

ALTER FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))  
       returns @temptable TABLE (items varchar(8000))  
      as  
      begin 
       set @String = RTRIM(LTRIM(@String)) 
       declare @idx int  
       declare @slice varchar(8000)  

       select @idx = 1  
        if len(@String)<1 or @String is null return  

       while @idx!= 0  
       begin  
        set @idx = charindex(@Delimiter,@String)  
        if @idx!=0  
         set @slice = left(@String,@idx - 1)  
        else  
         set @slice = @String  

        if(len(@slice)>0) 
         insert into @temptable(Items) values(@slice)  

        set @String = right(@String,len(@String) - @idx)  
        if len(@String) = 0 break  
       end 
      return  
      end 

当我写,

SELECT Items 
FROM Split('around the home,clean and protect,soaps and air fresheners,air fresheners',',') 

这会给我,

air fresheners 
around the home 
clean and protect 
soaps and air fresheners 

我需要保持秩序。

+2

[请始终创建时使用'dbo.'前缀和引用对象](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/bad-habits-to-kick-avoiding-the-schema-prefix.aspx)。特别是功能。 –

回答

3

一个更简单的功能:

CREATE FUNCTION dbo.SplitStrings_Ordered 
(
    @List  NVARCHAR(MAX), 
    @Delimiter NVARCHAR(255) 
) 
RETURNS @t TABLE([Index] INT IDENTITY(1,1), Item NVARCHAR(255)) 
AS 
BEGIN 
    INSERT @t(Item) SELECT SUBSTRING(@List, Number, 
     CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number) 
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) 
     FROM sys.all_objects) AS n(Number) 
    WHERE Number <= CONVERT(INT, LEN(@List)) 
     AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter 
    ORDER BY Number OPTION (MAXDOP 1); 

    RETURN; 
END 
GO 

DECLARE @s VARCHAR(MAX) = 'around the home,clean and protect,soaps and air' 
    + ' fresheners,air fresheners'; 

SELECT Item FROM dbo.SplitStrings_Ordered(@s, ',') ORDER BY [Index]; 
+0

不错,优秀的人 – user960567

+0

@ user960567请注意,如果您使用的分隔符> 1个字符,请稍加更新。 –

+0

谢谢。你的功能是否更好(在性能方面)比上述更好? – user960567

1

你的功能需要设置的命令列(在此示例中SEQ):

ALTER FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))  
      returns @temptable TABLE (seq int, items varchar(8000))  
     as  
     begin 
      set @String = RTRIM(LTRIM(@String)) 
      declare @idx int  
      declare @seq int 
      declare @slice varchar(8000)  

      set @seq=1 

      select @idx = 1  
       if len(@String)<1 or @String is null return  

      while @idx!= 0  
      begin  
       set @idx = charindex(@Delimiter,@String)  
       if @idx!=0  
        set @slice = left(@String,@idx - 1)  
       else  
        set @slice = @String  

       if(len(@slice)>0) 
       begin 
        set @seq = @seq + 1 
        insert into @temptable(seq, Items) values(@seq,@slice)  
       end 

       set @String = right(@String,len(@String) - @idx)  
       if len(@String) = 0 break  
      end 
     return  
     end 
GO 
SELECT * FROM Split('around the home,clean and protect,soaps and air fresheners,air fresheners',',') order by seq