在SQL Server中拆分分隔的字符串

时间:2015-03-03 00:09:48

标签: sql sql-server string tsql sql-server-2012

我有以下斜杠分隔的示例字符串,需要拆分它们:

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技能有点弱。当字符串中没有分隔符时,我应该更改什么才能使此函数返回正确的结果?

3 个答案:

答案 0 :(得分:0)

以下修复了您的“SPLIT”功能。在WHILE之前添加以下行。

 SET @chunk = @chunk + '/'

答案 1 :(得分: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

答案 2 :(得分:0)

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

if CHARINDEX(@delimiter, @chunk, @prevPos)= 0
    set @chunk=@chunk+@delimiter 

使用(@johns正确解决方案)