将标量值函数转换为嵌入式表值函数

问题描述 投票:-5回答:1

请将以下标量值函数转换为嵌入式表函数。目前非常慢。

CREATE FUNCTION [dbo].[abbrev_first_5_chars] ( @str NVARCHAR(2000) )
RETURNS NVARCHAR(2000)
AS
BEGIN
    DECLARE @retval NVARCHAR(2000);

    SET @str= ltrim(rtrim(@str));
    SET @retval= concat(LEFT(@str,5),' ');

    WHILE CHARINDEX(' ',@str,1)>0 BEGIN
        SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(' ',@str,5));
        SET @retval+=CONCAT(LEFT(@str,5),' ');
    END

    RETURN @retval;
END
GO
sql sql-server string tsql recursive-query
1个回答
0
投票

从评论:

我正在尝试获取长字符串中每个单词的前五个字符。例如'dyddiodhdd kdkldjd ahbdkdl shdjdl'下的字符串应返回:'dyddi kdkld ahbdk shdjd',同时保留现有空格。我创建的函数可以运行,但是速度太慢,因此需要转换为嵌入式表值函数。

您可以为此使用递归cte。

create function abbrev_first_5_chars (@str nvarchar(2000))
returns table as
return
    with cte as (
        select 
            cast(substring(@str, 1, charindex(' ',  @str) - 1) as nvarchar(5)) val,
            substring(@str + ' ', charindex(' ',  @str) + 1, len(@str)) rest,
            1 lvl
        union all
        select
            cast(substring(rest, 1, charindex(' ',  rest) - 1) as nvarchar(5)),
            substring(rest, charindex(' ',  rest) + 1, len(rest)),
            lvl + 1
        from cte
        where charindex(' ',  rest) > 0
    )
    select val, lvl from cte

递归cte遍历字符串,并解析每个单词的前5个字符。另外,它还会返回字符串中每个部分在lvl列中的位置。

Demo on DB Fiddle

select * from abbrev_first_5_chars('dyddiodhdd kdkldjd ahbdkdl shdjdl');
val | lvl:---- | -:dyddi | 1个kdkld | 2ahbdk | 3shdjd | 4
© www.soinside.com 2019 - 2024. All rights reserved.