2015-03-03 197 views
0

我有以下斜槓分隔例如字符串和需要分割他們:分割分隔字符串

Record---String 
1--------ABC 
2--------DEF/123 
3--------GHI/456/XYZ 

的字符串會始終有1 - 3件;不多也不少。

要分割他們,我一直在使用這個功能:

CREATE FUNCTION [dbo].[Split] (
@chunk VARCHAR(4000) 
,@delimiter CHAR(1) 
,@index INT 
) 
RETURNS VARCHAR(1000) 
AS 
BEGIN 
DECLARE @curIndex INT = 0 
    ,@pos INT = 1 
    ,@prevPos INT = 0 
    ,@result VARCHAR(1000) 

WHILE @pos > 0 
BEGIN 
    SET @pos = CHARINDEX(@delimiter, @chunk, @prevPos); 

    IF (@pos > 0) 
    BEGIN -- Characters between position and previous position 
     SET @result = SUBSTRING(@chunk, @prevPos, @pos - @prevPos) 
    END 
    ELSE 
    BEGIN -- Last Delim 
     SET @result = SUBSTRING(@chunk, @prevPos, LEN(@chunk)) 
    END 

    IF (@index = @curIndex) 
    BEGIN 
     RETURN @result 
    END 

    SET @prevPos = @pos + 1 
    SET @curIndex = @curIndex + 1; 
END 

RETURN '' -- Else Empty 
END 

要分割的字符串,我調用這個函數像這樣:

MyField1 = dbo.Split(MyInputString, '/', 0), 
MyField2 = dbo.Split(MyInputString, '/', 1), 
MyField3 = dbo.Split(MyInputString, '/', 2) 

預期的結果將是

Record 1: 
    MyField1 = ABC 
    MyField2 = NULL 
    MyField3 = NULL 
Record 2: 
    MyField1 = DEF 
    MyField2 = 123 
    MyField3 = NULL 
Record 3: 
    MyField1 = GHI 
    MyField2 = 456 
    MyField3 = XYZ 

它幾乎是做我希望的,除了記錄1的MyField1的最後一個字符被截斷導致「AB」而不是「ABC」。我相信這是因爲這個單部分字符串沒有斜線分隔符。

不幸的是,我沒有寫這個函數,我的SQL技能有點弱。當字符串中沒有分隔符時,應該怎樣改變這個函數才能返回正確的結果?

+2

看看這篇文章由亞倫貝特朗:HTTP: //sqlperformance.com/2012/07/t-sql-queries/split-strings – 2015-03-03 00:23:33

回答

0

以下內容修復了您的「SPLIT」功能。在WHILE之前添加以下行。

SET @chunk = @chunk + '/' 
+0

這糾正了即時問題。如果我有一個不同的分隔符,如逗號,有沒有辦法讓這個更具通用性? – Sesame 2015-03-03 16:13:53

+0

JohnS有正確的答案。爲了使它通用,我將函數改爲: – 2015-03-03 16:30:09

0

我會的,而之前的CHARINDEX移動到:

alter FUNCTION [dbo].[Split] (
@chunk VARCHAR(4000) 
,@delimiter CHAR(1) 
,@index INT 
) 
RETURNS VARCHAR(1000) 
AS 
BEGIN 
DECLARE @curIndex INT = 0 
    ,@pos INT = 1 
    ,@prevPos INT = 0 
    ,@result VARCHAR(1000) 

SET @pos = CHARINDEX(@delimiter, @chunk, @prevPos); 
if @pos= 0 return @chunk 

WHILE @pos > 0 
BEGIN 
    SET @pos = CHARINDEX(@delimiter, @chunk, @prevPos); 

    IF (@pos > 0) 
    BEGIN -- Characters between position and previous position 
     SET @result = SUBSTRING(@chunk, @prevPos, @pos - @prevPos) 
    END 
    ELSE 
    BEGIN -- Last Delim 
     SET @result = SUBSTRING(@chunk, @prevPos, LEN(@chunk)) 
    END 

    IF (@index = @curIndex) 
    BEGIN 
     RETURN @result 
    END 

    SET @prevPos = @pos + 1 
    SET @curIndex = @curIndex + 1; 
    SET @pos = CHARINDEX(@delimiter, @chunk, @prevPos); 
END 

RETURN @chunk -- Else Empty 
END 
+0

這確實停止了字符串的第一部分的截斷,但是,第一部分現在被複制到第二和第三部分,即MyField1 = ABC,MyField2 = ABC,MyField3 = ABC。有任何想法嗎? – Sesame 2015-03-03 16:13:01

0
DECLARE @curIndex INT = 0 
    ,@pos INT = 1 
    ,@prevPos INT = 0 
    ,@result VARCHAR(1000) 

if CHARINDEX(@delimiter, @chunk, @prevPos)= 0 
    set @[email protected][email protected] 

使用(@johns正確的解決方案)