具有联合的子字符串在用户定义的函数中工作方式不同
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) <= 40
与SUBSTRING(@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;
【讨论】:
以上是关于具有联合的子字符串在用户定义的函数中工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章
添加 UITextField 作为 UITableViewCell 的子视图在 IOS 6 中工作正常,但在 IOS 7 中它不起作用?