开发者

SQL Server 2008 T-SQL UDF Split() Tailoring

I'm useing SQL Ser 2008 and have a large table with only one column of data. The data is a random string with very little consistency. Eample: Name Account 445566 0010020056893010445478008 AFD 369. I've been working with a split function that a stackoverflow user suggested. It works great but the function assigns the split string into one column. I need a row of individual columns. The present result is 1col with values Name, Account, 445566,... in it but the result I'm looking for is col1 Name, col2 Account, col3 445566,... If anyone could provide some insight on how to tailor this script or its usage to get the desired result it would be much appreciated.

CREATE FUNCTION [dbo].[Split] 
(    
 @String varchar(max) 
,@Delimiter char 
) 
RETURNS @Results table 
( 
 Ordinal int 
,StringValue varchar(max) 
) 
as 
begin 

set @String = isnull(@String,'') 
set @Delimiter = isnull(@Delimiter,'') 

declare 
 @TempString varchar(max) = @String 
,@Ordinal int = 0 
,@CharIndex int = 0 

set @CharIndex = charindex(@Delimiter, @TempString) 
while @CharIndex != 0 begin      
    set @Ordinal += 1        
    insert @Results values 
    ( 
     @Ordinal 
    ,substring(@TempString, 0, @CharIndex) 
    )        
    set @TempString = substring(@TempString, @CharIndex + 1,开发者_开发知识库 len(@TempString) - @CharIndex)      
    set @CharIndex = charindex(@Delimiter, @TempString) 
end 

if @TempString != '' begin 
    set @Ordinal += 1  
    insert @Results values 
    ( 
     @Ordinal 
    ,@TempString 
    ) 
end 

return 
end 

--The usage:
SELECT    
* 
FROM    
mytable M    
CROSS APPLY    
[dbo].[Split] (M.TheColumn, ' ') S
Where rtrim(s.StringValue) != '' 


If you know that you have 6 columns in the string you can use a split functions that looks like this and of course modify the function to whatever number of columns you want. A function can not return a dynamic number of columns.

create function dbo.Split6(@String varchar(max), @Delimiter char(1)) 
returns table as return
(
  select
    substring(T.Col, 1, S1.Pos-1) as Col1,
    substring(T.Col, S1.Pos+1, S2.Pos-S1.Pos-1) as Col2,
    substring(T.Col, S2.Pos+1, S3.Pos-S2.Pos-1) as Col3,
    substring(T.Col, S3.Pos+1, S4.Pos-S3.Pos-1) as Col4,
    substring(T.Col, S4.Pos+1, S5.Pos-S4.Pos-1) as Col5,
    substring(T.Col, S5.Pos+1, S6.Pos-S5.Pos-1) as Col6
  from (select @String+replicate(@Delimiter, 6)) as T(Col)
    cross apply (select charindex(@Delimiter, T.Col, 1)) as S1(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S1.Pos+1)) as S2(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S2.Pos+1)) as S3(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S3.Pos+1)) as S4(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S4.Pos+1)) as S5(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S5.Pos+1)) as S6(Pos)
)

Test:

declare @T table (Col varchar(100))

insert into @T values
 ('Name Account 445566 0010020056893010445478008 AFD 369'),
 (''),
 ('1 2'),
 ('1  3')

select S.Col1, S.Col2, S.Col3, S.Col4, S.Col5, S.Col6
from @T as T
  cross apply
    dbo.Split6(T.Col, ' ') as S

Result:

Col1  Col2     Col3    Col4                       Col5  Col6
----  -------  ------  -------------------------  ----  ----
Name  Account  445566  0010020056893010445478008  AFD   369

1     2             
1              3            


You might try using a PIVOT.

http://msdn.microsoft.com/en-us/library/ms177410.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜