SQL server进阶技能篇:字符串内分拆截取
写这篇文章是由于最近遇到这么个需求:
已知某表的字段值,是无规律带逗号分隔的字符串,样式如下:
现在要按逗号拆分成四个字段,样式如下:
我网上查了很久也没有现成 的函数,只能自己想办法了。
先分析下,用最简单最笨的办法,就是substring函数和charindex函数,substring函数就是截取字符串,charindex函数目的是获取字符串中,某个字符的位置。
也就是说,用charindex函数获取第1,2,3个逗号的位置,然后再去截取,同时要考虑好有的字段没有3个逗号,就会报错的情况。
我按照这个思路自定义了一个函数,废话不多少,我把主要代码贴上并分步解释下:
一、先获取字符串中逗号的数量:
先定义个变量叫@cfq(拆分前),作为入参,然后获取这个变量中的逗号数量。这里百度有的写的很复杂,实际上有个取巧的办法:
select @dhsl=(select len(@cfq)-len(replace(@cfq,',','')))
意思就是用总的字符长度 - 去掉逗号后的字符长度=逗号数量。
编程嘛,思路很重要。
再新增一个入参叫@type,int型,也就是代表想查第几个字符串。
加个判断:如果@type> 逗号数量+1,或者入参@cfq为空,那么直接返回空值,防止报错,代码如下:
if @type>@dhsl+1 or isnull(@cfq,'')='' ---如果超过本身字符数就返回空值
begin
select @cfhzfc ='' ---拆分后字符串
end
二、定义一个长度变量@len后面截取要用到,同时在@cfq传入的值后面加个逗号,也是为了防止后面报错:
select @len =0,@cfq=@cfq+','
当逗号数量为0 时,也就是只有一段有效字符串,直接获取@cfq从第1个子字符到逗号前一个字符的值。
这话有点绕口,逗号数量为0 ,是指原来传入的字符串的逗号数量,后面我们又在 @cfq 最后加了个逗号,我说了是为了防止报错。看代码
if @dhsl=0
begin
select @cfhzfc1 =SUBSTRING(@cfq,1,charindex(',',@cfq)-1)
end
charindex函数后面第三个参数,指的是从第几位开始检索,如果没有传就从头开始。那么我们看下当@dhsl=1时候的代码:
if @dhsl=1
begin
select @cfhzfc1 =SUBSTRING(@cfq,1,charindex(',',@cfq)-1)
select @len =len(@cfhzfc1)+2
select @cfhzfc2 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
end
@len是获取越过第一个逗号之后的首个字符的位置,然后charindex(',',@cfq,@len)就是获取下一个逗号的位置。
三、按照同样的逻辑写出第三、第四个字符串的获取方式,也就是当原始入参中逗号数量为2和3时,获取数据代码如下:
if @dhsl=2
begin
select @cfhzfc1 =SUBSTRING(@cfq,1,charindex(',',@cfq)-1)
select @len =len(@cfhzfc1)+2
select @cfhzfc2 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
select @len =@len+len(@cfhzfc2)+1
select @cfhzfc3 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
if @dhsl=3
begin
select@cfhzfc1 =SUBSTRING(@cfq,1,charindex(',',@cfq)-1)
select @len =len(@cfhzfc1)+2
select @cfhzfc2 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
select @len =@len+len(@cfhzfc2)+1
select @cfhzfc3 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
select @len =@len+len(@cfhzfc3)+1
select @cfhzfc4 =SUBSTRING(@cfq,@len,charindex(',',@cfq,@len)-@len)
end
四、最后根据入参@type的要求,我们输出想要的结果:
select @cfhzfc =
case @type when 1 then @cfhzfc1
when 2 then @cfhzfc2