2011-05-11 46 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