2011-05-11 3 views
0

SQL Ser 2008을 사용하고 있으며 데이터 열이 하나 뿐인 큰 테이블이 있습니다. 데이터는 일관성이 거의없는 임의의 문자열입니다. 샘플 : 이름 계정 445566 0010020056893010445478008 AFD 369. 나는 stackoverflow 사용자가 제안한 분할 함수로 작업 해왔다. 그것은 잘 작동하지만 함수는 split 문자열을 하나의 열에 할당합니다. 개별 열이 필요합니다. 현재 결과는 이름, 계정, 445566 등의 값을 가진 1col입니다. 그러나 찾고있는 결과는 col1 Name, col2 Account, 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

Incidently,이 기능은 @antisanity에서 차용하고 테이블에의 사용이 @gbn에서왔다. 고마워! – 2boolORNOT2bool

+0

달성하려는 목표는 무엇입니까? 이 데이터가 유지 관리되고 있습니까 아니면 가져 오기입니까? 출력 테이블의 너비가 달라 지거나 정적일까요? – canon

+0

저는 이전 플랫 파일 배치를 리버스 엔지니어링합니다. 데이터는 120자를 포함하는 문자열로 구성됩니다. 테이블 너비는 정적 열 수입니다. 내 목표는 모든 데이터가 포함 된 하나의 열뿐만 아니라 9 또는 10 개의 열을 포함하는 열의 행으로 문자열을 나눕니다. 이것은 한 번에 10000 행의 데이터에 영향을 미칩니다. 어떤 도움을 주셔서 다시 고맙습니다! – 2boolORNOT2bool

답변

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

0

PIVOT을 사용해 볼 수도 있습니다.

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

+0

스크립트를 사용한 후에 테이블 열을 PIVOT 할 수 있어야하지만 그 주위의 방법을 찾고있었습니다. 내 생각은 당신이 문자열을 분할하고 하나의 열에 데이터를 삽입 할 수 있다면 어쩌면 스크립트 내에서 여러 다른 열에 할당 할 수 있었다. – 2boolORNOT2bool

+0

나는 이것이 가장 명백한 도구를 사용하지 않는 것처럼 들리지만 성능이 절반이라고 생각한다. (100000 개가 넘는 행을 가진 테이블을 피벗 시키면 CPU가 두 번 울리면 안된다. 시간이 지남), 절반 만이이 일을 할 수 있는지 보려고합니다. 나는 T-SQL에 능숙하지 않아서 전문가에게 물어볼 것이라고 생각했습니다. – 2boolORNOT2bool