2011-05-11 93 views
0

我正在使用SQL Ser 2008,并且只有一列数据的大表。数据是一个随机字符串,一致性很低。例如:名称帐户445566 0010020056893010445478008 AFD 369.我一直在使用一个用户提示的分支函数。它工作得很好,但函数将分割字符串分配到一列中。我需要一排单列。目前的结果是1col,其中包含值名称,帐户,445566,...,但我要查找的结果是col1名称,col2帐户,col3 445566,... 如果任何人都可以提供一些关于如何定制这个脚本或它的用法来获得所需的结果,这将非常感激。SQL Server 2008 T-SQL UDF分割()裁剪

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) != '' 
+0

顺便说一句,该功能是从@antisanity借其使用在桌子上,从@gbn来了。多谢你们! – 2boolORNOT2bool 2011-05-11 18:32:01

+0

你想达到什么目的?这些数据是维护的还是重要的?输出表格的宽度是否会变化或是静态的? – canon 2011-05-11 19:00:55

+0

我正在逆向工程旧的平面文件批处理。数据由包含120个字符的字符串组成。表格宽度将是一个静态的列数。我的目标是将字符串拆分为一列,而不仅仅是一列包含所有数据,但包含9或10列。这会影响每次10000行数据。再次感谢反对任何帮助! – 2boolORNOT2bool 2011-05-11 21:13:51

回答

1

如果你知道你在字符串中6列,你可以使用拆分功能,看起来像这样,当然还有修改功能所需的列的任何数字。函数不能返回动态数量的列。

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

测试:

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 

结果:

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

1  2    
1    3    
+0

这看起来不错。我最终会发现我需要多少列,所以我认为这会很好地工作!谢谢! – 2boolORNOT2bool 2011-05-12 14:10:50

0
+0

脚本被使用后,我应该可以使用PIVOT表格列,但我正在寻找一种解决方法。我的想法是,如果你可以拆分一个字符串并将数据插入到一列,也许你可以将它分配给脚本中的几个不同的列。 – 2boolORNOT2bool 2011-05-11 21:17:19

+0

我知道这听起来像我没有使用最明显的工具,但我有半性能的表现(旋转一个超过100000行的表希望不会触及CPU两次仍然需要一段时间,加上发生的几个过程时间过去了),一半只是试图看看是否可以完成。我不熟悉T-Sql,所以我想我会问专家。 – 2boolORNOT2bool 2011-05-11 21:49:06