具有联合的子字符串在用户定义的函数中工作方式不同

Posted

技术标签:

【中文标题】具有联合的子字符串在用户定义的函数中工作方式不同【英文标题】:Substring with union working differently in a User Defined Function 【发布时间】:2021-08-18 19:53:14 【问题描述】:

我正在尝试使用 SQL UDF 将包含无限字符的句子拆分为 7 的倍数。这意味着我试图将一个句子分成每行 7 个字符的行。这是我觉得最快的方法。

CREATE OR ALTER FUNCTION dbo.UDF_SplitStringIntoRows
(
    @inputstring nvarchar(MAX)
)
RETURNS @OutputTbl TABLE
(
    txt nvarchar(MAX),
    seq INT IDENTITY 
)
AS
BEGIN
    IF(LEN(@inputstring) <= 40)
    BEGIN 
        INSERT INTO @OutputTbl (txt) 
            SELECT SUBSTRING(@inputstring, 1,7) UNION 
            SELECT SUBSTRING(@inputstring, 8,7) UNION 
            SELECT SUBSTRING(@inputstring, 15,7) UNION 
            SELECT SUBSTRING(@inputstring, 23,7) UNION 
            SELECT SUBSTRING(@inputstring, 30,7) UNION 
            SELECT SUBSTRING(@inputstring, 37,7) UNION 
            SELECT SUBSTRING(@inputstring, 44,7)
    END

    RETURN
END

我的查询:

SELECT *
FROM dbo.UDF_SplitStringIntoRows('This is a demo function which') AS USSIR
WHERE USSIR.txt <> ''

输出:

这弄乱了句子的顺序。我在这里错过了什么吗?请提出建议。

【问题讨论】:

您的函数似乎每行分成 7 个字符,这不是您所要求的,示例数据和所需结果可能会有所帮助。 有很多更好的方法来分割字符串而不需要多重选择和联合,看看使用cross apply和一个tally表 您的子字符串计算中也有一个错误 LEN(@inputstring) &lt;= 40SUBSTRING(@inputstring, 44,7)一致吗? 如果您只期望一个 40 (44?) 个字符的字符串,为什么要使用 nvarchar(max)?如果你传递一个超过 40 个字符的字符串会发生什么(函数会很高兴占用兆字节)? 【参考方案1】:

刚刚发现了错误。实际上是联盟搞砸了。我刚刚用 Union All 替换了 Union,它似乎正在获取所需的输出。

再次感谢。

【讨论】:

【参考方案2】:

使用内联表函数会更好

CREATE OR ALTER FUNCTION dbo.UDF_SplitStringIntoRows
(
    @inputstring nvarchar(56),
    @splitSize int
)
AS RETURN

SELECT
    SUBSTRING(@inputstring, n * @splitSize + 1, @splitSize) txt,
    ROW_NUMBER() OVER (ORDER BY n) seq
FROM (VALUES
  (0),(1),(2),(3),(4),(5),(6),(7)
) v(n)
WHERE n * @splitSize + 1 >= LEN(@inputstring);

GO

如果字符串可以无限长,可以使用Itzik Ben-Gan's tally function生成行

CREATE OR ALTER FUNCTION dbo.GetNums
  (@low AS BIGINT = 1, @high AS BIGINT)
RETURNS TABLE
AS
RETURN
 
  WITH
    L0 AS ( SELECT 1 AS c 
            FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
                        (1),(1),(1),(1),(1),(1),(1),(1)) AS D(c) ),
    L1 AS ( SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B ),
    L2 AS ( SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B ),
    L3 AS ( SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B ),
    Nums AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
              FROM L3 )
  SELECT TOP(@high - @low + 1)
     rownum AS rn,
     @high + 1 - rownum AS op,
     @low - 1 + rownum AS n
  FROM Nums
  ORDER BY rownum;

GO
CREATE OR ALTER FUNCTION dbo.UDF_SplitStringIntoRows
(
    @inputstring nvarchar(MAX),
    @splitSize int
)
AS RETURN

SELECT
    SUBSTRING(@inputstring, n * @splitSize + 1, @splitSize) txt,
    rownum AS seq
FROM dbo.GetNums(0, (LEN(@inputstring) - 1) / @splitSize) v;

【讨论】:

以上是关于具有联合的子字符串在用户定义的函数中工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

udf(用户定义函数)如何在 pyspark 中工作?

添加 UITextField 作为 UITableViewCell 的子视图在 IOS 6 中工作正常,但在 IOS 7 中它不起作用?

选择语句中的子查询如何在 oracle 中工作

内核模块的加载如何在 linux 中工作?

工作线程如何在Nodejs中工作?

多个并且在mysql中工作或不工作[重复]