SQL Server iTVF,用于在收到空值时根据指定分隔符将字符串拆分为一行子字符串(TSQL)

ffx8fchx  于 2022-11-21  发布在  其他
关注(0)|答案(2)|浏览(147)

我有一个内联表值函数,它根据指定分隔符将字符串拆分为子字符串行。
具体如下:

ALTER FUNCTION [dbo].[SplitString]
    (@List NVARCHAR(MAX),
     @Delim VARCHAR(255))
RETURNS TABLE
AS
    RETURN 
        (SELECT [Value], idx = RANK() OVER (ORDER BY n) 
         FROM 
             (SELECT 
                  n = Number, 
                  [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
                  CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
              FROM 
                  (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
                   FROM sys.all_objects) AS x
              WHERE Number <= LEN(@List)
                AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim) AS y
        );
GO

用法:

SELECT value 
FROM dbo.SplitString('a|b|c', '|')

退货:
| 价值观|
| - -|
| 一种|
| B|
| C语言|
但是,当发送空值作为第一个参数时,它不会返回任何内容。
例如:

SELECT value FROM dbo.SplitString('','|')

这不会传回任何东西。
我需要对dbo.SplitString函数做什么修改,以便当一个空字符串作为第一个参数传入时,它返回一个空结果集?
PS:由于兼容性问题,我不能使用内置的STRING_SPLIT函数。

q0qdq0h2

q0qdq0h21#

DelimitedSplit8K_LEAD(如上所述)将始终返回一行,并且速度会更快。
也就是说,为了便于学习,让我们修改一下函数。如果用分隔符替换一个空值,就可以得到想要的结果。只需要替换@list with ISNULL(NULLIF(@List,''),@Delim)的每个示例。现在,您有:

ALTER FUNCTION [dbo].[SplitString]
    (@List NVARCHAR(MAX),
     @Delim VARCHAR(255))
RETURNS TABLE
AS
    RETURN 
        (SELECT [Value], idx = RANK() OVER (ORDER BY n) 
         FROM 
             (SELECT 
                  n = Number, 
                  [Value] =     LTRIM(RTRIM(SUBSTRING(ISNULL(NULLIF(@List,''),@Delim), [Number],
              CHARINDEX(@Delim, ISNULL(NULLIF(@List,''),@Delim) + @Delim, [Number]) - [Number])))
              FROM 
                  (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
                   FROM sys.all_objects) AS x
              WHERE Number <= LEN(ISNULL(NULLIF(@List,''),@Delim))
                AND SUBSTRING(@Delim + ISNULL(NULLIF(@List,''),@Delim),         
[Number], LEN(@Delim)) = @Delim) AS y
        );

现在,当您执行:声明@列表VARCHAR(最大值)=',@分隔符VARCHAR(255)= '|'

SELECT *
FROM dbo.SplitString(@list,@delim)

您可以获得:

Value    idx
------   ------
         1
3yhwsihp

3yhwsihp2#

感谢@Larnu和@Bernie的所有建议。
经过这么多的研究,我开始迭代并得到预期的结果。我通过简单的while循环和SQL的字符串函数实现了这一点。

CREATE FUNCTION [SplitString]
(
   @ActualString      VARCHAR(MAX),
   @DelimiterCharacter  VARCHAR(10)
)
RETURNS @TableRes TABLE (Id INT IDENTITY(1,1),Value VARCHAR(MAX))
AS
BEGIN
DECLARE @SubStr VARCHAR(MAX)
     WHILE (CHARINDEX(@DelimiterCharacter  ,@ActualString)<>0)
     BEGIN
         SET @SubStr=SUBSTRING(@ActualString,1,CHARINDEX(@DelimiterCharacter ,@ActualString)-1)
         SET @ActualString= STUFF(@ActualString,1,CHARINDEX(@DelimiterCharacter,@ActualString),'') 
         INSERT INTO @TableRes
         SELECT @SubStr

      END
       INSERT INTO @TableRes
       SELECT @ActualString

       RETURN
END

这适用于所有情况
1)当实际字符串为空字符串(如select * from [dbo].[SplitString]('',','))时
2)当实际字符串结尾为空字符串时,如select * from [dbo].[SplitString]('a,b,',',')

相关问题