优化查找字符串中第 N 次出现的字符

2023-12-23

我编写了一个 sql server 函数,它返回第 N 次出现的字符之前的子字符串。

例如,SELECT dbo.fn_getFirstNthSentence('.', 'hello world.It.is.raining.today', 3)返回 '​​hello world.It.Is.'因此。

我写的函数看起来又脏又慢,所以我想优化它。 任何使其清洁的建议都将受到赞赏。

谢谢。

CREATE FUNCTION fn_getFirstNthSentence
(
  @TargetStr VARCHAR(MAX) ,
  @SearchedStr VARCHAR(8000) ,
  @Occurrence INT
)
RETURNS varchar(MAX)
AS
BEGIN

    DECLARE @pos INT ,
        @counter INT ,
        @ret INT;

    SET @pos = CHARINDEX(@TargetStr, @SearchedStr);

    IF ( @pos = 0 )
        RETURN @SearchedStr

    SET @counter = 1;

    IF @Occurrence = 1
        SET @ret = @pos;

    ELSE
        BEGIN

            WHILE ( @counter < @Occurrence )
                BEGIN

                    IF(LEN(@SearchedStr) < @pos + 1)
                        RETURN @SearchedStr

                    SELECT  @ret = CHARINDEX(@TargetStr, @SearchedStr,
                                             @pos + 1);
                    IF(@ret = 0)
                        RETURN @SearchedStr
                    SET @counter = @counter + 1;
                    SET @pos = @ret;
                END;
        END;
    RETURN LEFT(@SearchedStr, @ret)
END;

这是使用分隔字符串拆分器的另一个选项。已经发布的 XML 方法是一个很好的方法,但这种方法不需要表变量。

这是作为内联表值函数创建的,它应该保持非常快的性能。

create function fn_getFirstNthSentence
(
    @SearchedStr varchar(100)
    , @Occurrence int
    , @Delimiter char(1)
) returns table as return

    with ParsedValues as
    (
        select Item
            , ItemNumber
        from dbo.DelimitedSplit8K(@SearchedStr, @Delimiter)
        where ItemNumber <= @Occurrence
    )

    select top 1 ResultString = STUFF(
    (
        select @Delimiter + Item
        from ParsedValues
        order by ItemNumber
        for xml path('')), 1,1, '') + @Delimiter
    from ParsedValues

这也使用了 Jeff Moden 创建的分离器。它有一个功能,其他拆分器都没有...一列来指示值来自哪个位置。您可以在此处找到他的文章以及随后的讨论。http://www.sqlservercentral.com/articles/Tally+Table/72993/ http://www.sqlservercentral.com/articles/Tally+Table/72993/

然后如果你想执行它,你可以非常简单地做到这一点。

declare @String varchar(100) = 'hello world.It.is.raining.today.'
    , @Num int = 3
    , @Delimiter char(1) = '.'
;

select *
from fn_getFirstNthSentence(@String, @Num, @Delimiter)

如果您不喜欢 Jeff Moden 的分离器,您可以在这里找到其他几个选项。http://sqlperformance.com/2012/07/t-sql-queries/split-strings http://sqlperformance.com/2012/07/t-sql-queries/split-strings我不会在所有事情上都使用 Moden,但是当你需要保持解析值的顺序时,它就很棒了。

--EDIT--

以下是如何将其修改为标量函数而不是内联表值函数。我的偏好是保留 itvf,因为它们更快、更灵活。

create function fn_getFirstNthSentenceScalar
(
    @SearchedStr varchar(100) = 'hello world.It.is.raining.today.this is after 5'
    , @Occurrence int = 5
    , @Delimiter char(1) = '.'
) returns varchar(max) as begin

    declare @RetVal varchar(max);

    with ParsedValues as
    (
        select Item
            , ItemNumber
        from dbo.DelimitedSplit8K(@SearchedStr, @Delimiter)
        where ItemNumber <= @Occurrence
    )

    select top 1 @RetVal = STUFF(
    (
        select @Delimiter + Item
        from ParsedValues
        order by ItemNumber
        for xml path('')), 1,1, '') + @Delimiter
    from ParsedValues;

    return @RetVal
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

优化查找字符串中第 N 次出现的字符 的相关文章

  • SQL 性能,使用 OPTION (FAST n)

    谁能告诉我在 SQL 查询中使用 OPTION FAST n 有什么缺点 比如我这么快就抓取了10万条记录 但这对SQL Server的其他进程有影响吗 我正在接近我的问题 我必须每周运行一次数据处理 因此 第一个结果会在 5 7 秒后出现
  • Linq 选择与另一个表中的 ID 相等的项目

    我不确定这怎么可能 但我有两个表 我想通过表 1 的值从表 2 中获取值 表 1 有一个名为 rank 的外键 它是int 表 2 有一个名为 name 的值 它是string 现在表 1 的 排名 与表 2 的 ID 相关 所以当我说 v
  • LINQ to SQL:从位于不同服务器上的两个数据库获取记录

    我需要从两个不同的表中获取记录 数据库位于两个不同的 SQL Server 中 例如 销售数据库位于服务器 1 上 采购数据库位于服务器 2 上 销售和采购数据库都有一些表集 例如销售数据库中的 table1 和采购数据库中的 table2
  • 从 SQL Server 中的子查询值或其他聚合函数获取平均值

    我有 SQL 语句 SQL Server SELECT COUNT ActionName AS pageCount FROM tbl 22 Benchmark WHERE DATEPART dw CreationDate gt 1 AND
  • 从 bak 文件恢复数据库 sql server 的脚本不起作用

    我有一个空数据库 DB Clients 我想从一个恢复数据库 bak file OldDBClients bak 这是路径 C OldDBClients bak 这是我的脚本 USE master GO RESTORE DATABASE D
  • TSQL - 执行CLR权限

    我从 CLR net Assembly 获得了一个 sql 过程 该过程在执行时返回错误 Msg 6522 Level 16 State 1 Procedure sp HelloWorld Line 0 A NET Framework er
  • SQL Server 标识列值从 0 而不是 1 开始

    我遇到了一个奇怪的情况 数据库中的某些表的 ID 从 0 开始 即使 TABLE CREATE 的 IDENTITY 1 1 也是如此 对于某些表来说是这样 但对于其他表则不然 它一直有效到今天 我尝试过重置身份列 DBCC CHECKID
  • 如何在SQL Compact Edition中导入数据? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我似乎没有找到合适的工具 也没有找到
  • 解释 SQL Server 中 sys.objects 中的类型代码

    在 SQL Server 上 sys objects 表包含 Type 和 Type Desc 属性 例如 对于我的一个数据库 SELECT DISTINCT Type Type Desc FROM Sys Objects ORDER BY
  • 从VBA中的数组批量插入到sql中

    我正在尝试在 Excel 中构建一个按钮 将所选区域上传到 SQL Server 中的表中 第一行将自动视为列标题 这件事该怎么继续下去呢 我想要的是简单和超快的上传 这是我的想法 我将选择选定的区域 然后将其保存为 txt 文件 然后对其
  • SSRS。如何在table1_Details_Group右侧创建新的行组?

    我正在使用 Microsoft Visual Studio 2013 创建报告 PROBLEM 如果我添加新的Row Group前面会自动添加table1 Details Group 问题 如何更改组的顺序或在右侧添加新组table1 De
  • 如何在 SQL Server 中添加具有自动增量值的字符串?

    如何在SQL Server中添加具有自动增量值的字符串 create table date sno int emp identity 1 1 我需要以下作为输出 emp 1 emp 2 用普通定义你的表INT IDENTITY column
  • SQL Server 查询结果集的大小

    SQL Server 中是否有确定结果集中 Mgmt Studio 查询中返回的数据大小 以 MEGS 为单位 您可以打开客户端统计信息 查询菜单 包括客户端统计信息 它给出执行查询时从服务器返回的字节数
  • SQL - 为每条记录调用存储过程

    我正在寻找一种方法来为 select 语句的每条记录调用存储过程 SELECT SomeIds SELECT spro Id FROM SomeTable as spro INNER JOIN Address addr ON addr Id
  • SQL Server Express 到 .mdf 文件的连接

    两部分问题 我使用 VS 2015 Update 3 创建了一个 ASP NET MVC 5 应用程序 我在本地计算机上完成了该项目 突然 我无法再通过 SQL Server 对象资源管理器连接到 mdf数据库文件并出现以下错误 无法打开数
  • SQL Server 差异工具

    在一个团队中工作时 人们很容易修改开发 SQL Server 表并忘记它 或者准备部署更改但必须等待部署 这使得我们的开发表和活动表不一致 从而在推送存储过程时导致问题 是否有一个工具可以让我输入 SPROC 名称并让它检查开发数据库和实时
  • 如何找出我的 MS SQL Server 排序规则是什么?

    是否有我可以执行的 SQL 来找出答案 服务器默认排序规则 select serverproperty collation 哪个是相同的 select databasepropertyex master collation Check 服务
  • SQL Group BY,每个组的前 N ​​个项目

    我有一个 SQL 查询 可以获取给定商店中销量最高的 5 件商品 SELECT TOP 5 S UPCCode SUM TotalDollarSales FROM Sales S WHERE S StoreId 1 GROUP BY S U
  • 在存储过程结束时显式删除本地临时表有什么好处?

    考虑以下伪 T SQL 代码 由存储过程执行 CREATE TABLE localTable
  • sql查询中的truncate和delete命令有什么区别[重复]

    这个问题在这里已经有答案了 可能的重复 SQL中TRUNCATE和DELETE有什么区别 https stackoverflow com questions 139630 whats the difference between trunc

随机推荐