在 SQL 服务器中拆分定界字符串

Split delimited string in 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技术有点弱。当字符串中没有定界符时,我应该更改什么以使此函数 return 获得正确的结果?

以下修复了您的 "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 正确的解决方案)