SQL Server中的拆分分隔字符串



我有以下用斜线分隔的示例字符串,需要对它们进行拆分:

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

以下修复了您的"SPLIT"函数。在WHILE之前添加以下行。

 SET @chunk = @chunk + '/'

我会将charindex移到while之前:

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
DECLARE @curIndex INT = 0
    ,@pos INT = 1
    ,@prevPos INT = 0
    ,@result VARCHAR(1000)
if CHARINDEX(@delimiter, @chunk, @prevPos)= 0
    set @chunk=@chunk+@delimiter 

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

最新更新