`
xiaoer_1982
  • 浏览: 1831394 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

用TSQL求子串在父串中出现的次数

阅读更多

 导言

  由于SQL Server本身没提供计算一个字符串在另一个字符串重复次数的函数,大家按照自己的思路使用自定义函数实现了该功能,并在网上传播。我阅读了同事从网上获取的该函数的一个版本后,便发现该函数存在一个明显的逻辑错误。为了进一步确认这个问题,我在Google上搜索相关关键字,发现该功能多数的实现思路一致,但大多数都存在这个共同的逻辑错误。可见从网络上获取的一些资源,可以作为参考,但要在实际需求中能够应用,是需要仔细检查的。

  功能实现

  常见方法

  以下是网上一种较常见的函数实现:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

--描述:利用循环得到一个字符串在另一个字符串中出现的次数
--DEMO:
--SELECT dbo.f_getcharcount_false('df ththth','tht')
CREATE FUNCTION [dbo].[f_getcharcount_false](
@str varchar(8000),
@chr varchar(8000)
) RETURNS INT
AS
BEGIN
DECLARE @re INT,@i INT
SELECT @re=0,@i=charindex(@chr,@str)+1
WHILE @i>1
SELECT @re=@re+1
,@str=substring(@str,@i,8000)
,@i=charindex(@chr,@str)+1

RETURN(@re)
END

  上面的函数设计思路是循环截断源字符串,通过计算截断的次数来获取子字符串出现的重复数。思路当然是可行的,但是在它截断的时候,起点是@i=charindex(@chr,@str)+1,这里就是错误的起因。以我给出的DEMO来讲,代码如下:

  SELECT dbo.f_getcharcount_false('df ththth','tht')

  结果为2,其实明显,正确的结果是1。因为上述函数的截断内容只有“t”,而后面的“ht”会被继续使用,导致“t”与后面的“ht”组合,结果计数多了一次。正确的截取位置应该从子串的位置结束处开始,就是从“tht”后面开始。

  既然思路正确,那么我们就修改上述代码中的错误,修改后的代码如下:第1页:null 第2页:null 第3页:null

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

--描述:利用循环得到一个字符串在另一个字符串中出现的次数
--DEMO:
--SELECT dbo.f_getcharcount_true('df ththth','tht')
CREATE FUNCTION [dbo].[f_getcharcount_true](
@str varchar(8000),
@chr varchar(8000)
) RETURNS INT
AS
BEGIN
DECLARE @re INT,@i INT
SELECT @re=0,@i=charindex(@chr,@str)+1
WHILE @i>1
SELECT @re=@re+1
,@str=substring(@str,@i-1+len(@chr),8000)
,@i=charindex(@chr,@str)+1
RETURN(@re)
END

  当然,截断字符串很多人喜欢用stuff填充空字符,但网上流传的该版本,用stuff函数实现截断操作的,多数也是存在这个截断位置错误的。

  优化的方法

  上面讲的只是在网络上流传最广泛的方法,那么想要精炼代码,寻找更便捷和高效的方法也是可行。下面再介绍两种较便捷的实现方式。

  <方法一>

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


/*
描述:
利用字符串长度计算字符出现次数
DEMO:
SELECT dbo.f_get_char_repeat_count('df ththth','tht')
*/
CREATE FUNCTION [dbo].[f_get_char_repeat_count]
(@str VARCHAR(8000),
@substr VARCHAR(8000)
)
RETURNS INT
BEGIN
RETURN (LEN(@str)-LEN(REPLACE(@str,@substr,'')))/LEN(@substr)
END

第1页:null 第2页:null 第3页:null

  <方法二>

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*
描述:利用长度差值求重复次数
DEMO:
SELECT fn_get_char_repeat_count_by_add_char('ahahaahde','ah')
*/
CREATE FUNCTION [dbo].[fn_get_char_repeat_count_by_add_char](
@str varchar(8000),--父串
@chr varchar(8000) --子串
) RETURNS INT
AS
BEGIN
RETURN(len(replace(@str,@chr,@chr+' '))-len(@str))
END

  上面的<方法一>是用空字符替换父字符串中出现的子串,用剩余字符串的长度与子字符串的长度求商;<方法二>是把为父字符串中出现子字符串的地方都增加个空格,用替换后的父字符串长度减去原父字符串的长度。

本文转自:http://www.techrss.cn/html/2008/03-30/78902.htm

分享到:
评论

相关推荐

    PLSQL与TSQL一些语法区别

    对于可变长度的字符串,TSQL用varchar(m),PL/SQL则使用varchar2(m)。值得注意的是,PL/SQL的varchar2不同于TSQL的varchar。 - TSQL的datetime对应于PL/SQL的date,但PL/SQL没有单独的时间类型。 - 在PL/SQL中,...

    TSQL 分组集1

    在SQL的世界里,TSQL(Transact-SQL)是Microsoft SQL Server所使用的扩展SQL语言,它包含了许多高级特性,其中之一便是分组集(Grouping Sets)。分组集允许我们在一个查询中实现多维度的分组,这对于数据分析和...

    sql 入门 tsql 入门

    sql 入门 tsql 入门 sql 实例,sql 简单教程 sql 教程

    TSQL参考实用教程(chm)

    很详细的TSQL教程,对于学习TSQL的朋友会有用的

    TSQL 学习资料

    TSQL,全称为Transact-SQL,是SQL(Structured Query Language)的一个扩展,主要用于Microsoft SQL ...对于那些想要在SQL Server环境中工作的人来说,这份资料是一个宝贵的资源,能够帮助他们建立坚实的TSQL基础。

    TSQL2012.sql

    TSQL2012数据库脚本下载

    TSQL 存储过程 和 游标

    存储过程中不使用`GO`语句,因为`GO`在批处理中用于分隔命令,而存储过程本身就是一个批处理。 总之,TSQL的存储过程和游标是数据库管理和数据操作的重要工具。存储过程增强了SQL语言的功能,提高了代码复用性,...

    TSQL与PLSQL比较

    把TSQL与PLSQL之间所有的信息按照不同功能进行了的描述。

    TSQL语言,数据库

    TSQL语言,适合数据库初学者,及要设计到数据库开发的对数据库不太熟悉的。

    TSQL_Programming_20061113

    TSQL_Programming_20061113

    TSQL编程1-规则.pdf

    TSQL编程1-规则.pdf

    SQLSERVER TSQL 源码

    《SQL SERVER 2008技术内幕:T-SQL语言基础》随书出来的源码。在学习这本书时,一定要在SQLSERVER2008上面创建这个数据库,供实验,一定要多做实验,才能有效掌握SQL语句的编写。

    使用TSQL建库建表PPT课件.pptx

    首先,课程强调了TSQL在数据库管理中的重要性,尤其是在实现C#、Java等编程语言与数据库交互时的作用。课程结构涵盖了从基础的SQL知识到更高级的Java OOP、Web服务等技术。 在数据库基础知识部分,讲解了数据库文件...

    数据库 TSQL程序设计基础PPT学习教案.pptx

    数据库 TSQL程序设计基础PPT学习教案.pptx

    TSQL 存储过程 游标 数据库 sql优化 存储过程分页

    TSQL 存储过程 游标 数据库 sql优化 存储过程分页 TSQL 存储过程 游标 数据库 sql优化 存储过程分页 TSQL 存储过程 游标 数据库 sql优化 存储过程分页 TSQL 存储过程 游标 数据库 sql优化 存储过程分页 TSQL 存储...

    Sqlserver Tsql 分页

    1.between and方法 2.offset xx rows fetch next xx rows only方法

    使用TSQL建库建表学习教案.pptx

    使用TSQL建库建表学习教案.pptx

    tsql语言的乘法表

    论坛里面找的 乘法表 比较有意思 大家看看

    使用TSQL建库建表PPT学习教案.pptx

    使用TSQL建库建表PPT学习教案.pptx

    用TSQL语句完成创建与管理表操作练习.pdf

    本资源摘要信息对应的文件是《用TSQL语句完成创建与管理表操作练习.pdf》,主要介绍了使用TSQL语句创建和管理表的操作步骤。 表结构设计 在本实践中,我们设计了三个表:XS、TS和JY。 1. XS表:存放学生基本信息...

Global site tag (gtag.js) - Google Analytics