????? 在给文章加自定义标签时,需要在存储过程中对输入的字符串按照“,”字符分割成一个字符数组。但是Sql中没有实现字符串分组的Split方法。因此就需要编写一个自定义的Split函数。我首先是使用表值函数的方法实现的字符串分组,但是在使用中感觉不是很方便。后来又在网上找到了一种使用两个标量函数,其中一个函数首先返回分割后字符数组的长度,另一个函数依次返回每个分割出的字符串。然后使用循环依次获取分割的字符。
表值函数实现Split方法
?(
?????@SplitString?nvarchar(max),
?????@Separator?nvarchar(10)='?'
?)
?RETURNS?@SplitStringsTable?TABLE
?(
?[id]?int?identity(1,1),
?[value]?nvarchar(max)
?)
?AS
?BEGIN
?????DECLARE?@CurrentIndex?int;
?????DECLARE?@NextIndex?int;
?????DECLARE?@ReturnText?nvarchar(max);
?????SELECT?@CurrentIndex=1;
?????WHILE(@CurrentIndex<=len(@SplitString))
?????????BEGIN
?????????????SELECT?@NextIndex=charindex(@Separator,@SplitString,@CurrentIndex);
?????????????IF(@NextIndex=0?OR?@NextIndex?IS?NULL)
?????????????????SELECT?@NextIndex=len(@SplitString)+1;
?????????????????SELECT?@ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex);
?????????????????INSERT?INTO?@SplitStringsTable([value])?VALUES(@ReturnText);
?????????????????SELECT?@CurrentIndex=@NextIndex+1;
?????????????END
?????RETURN;
?END
?
select * FROm dbo.SplitToTable('111,b2222,323232,32d,e,323232f,g3222', ',')
结果为
id????????? value
----------- ---------------------------------------
1?????????? 111
2?????????? b2222
3?????????? 323232
4?????????? 32d
5?????????? e
6?????????? 323232f
7?????????? g3222
(7 行受影响)
?
使用循环的方法
首先GetSplitLength函数返回分割后的字符数组的长度。
?
?(
??@String?nvarchar(max),??--要分割的字符串
??@Split?nvarchar(10)??--分隔符号
?)
?returns?int
?as
?begin
??declare?@location?int
??declare?@start?int
??declare?@length?int
?
??set?@String=ltrim(rtrim(@String))
??set?@location=charindex(@split,@String)
??set?@length=1
??while?@location<>0
??begin
????set?@start=@location+1
????set?@location=charindex(@split,@String,@start)
????set?@length=@length+1
??end
??return?@length
?end
?
?
select dbo.GetSplitLength('111,b2222,323232,32d,e,323232f,g3222',',')
结果为7。
?
GetSplitOfIndex函数是按顺序分别获取分割后的字符串。
?
?(
??@String?nvarchar(max),??--要分割的字符串
??@split?nvarchar(10),??--分隔符号
??@index?int?--取第几个元素
?)
?returns?nvarchar(1024)
?as
?begin
??declare?@location?int
??declare?@start?int
??declare?@next?int
??declare?@seed?int
?
??set?@String=ltrim(rtrim(@String))
??set?@start=1
??set?@next=1
??set?@seed=len(@split)
??
??set?@location=charindex(@split,@String)
??while?@location<>0?and?@index>@next
??begin
????set?@start=@location+@seed
????set?@location=charindex(@split,@String,@start)
????set?@next=@next+1
??end
??if?@location?=0?select?@location?=len(@String)+1?
??
??return?substring(@String,@start,@location-@start)
?end
?
?
select dbo.GetSplitOfIndex('111,b2222,323232,32d,e,323232f,g3222',',', 3)
结果323232。
?
?
?SELECT?@Tags='111,b2222,323232,32d,e,323232f,g3222';
?DECLARE?@Tag?nvarchar(1000)
?DECLARE?@next?int;
?set?@next=1
?
?DECLARE?@Length?int;
?SELECT?@Length=dbo.GetSplitLength(@Tags,',')
?while?@next<=@Length
?begin
?????SET?@Tag?=?left(dbo.GetSplitOfIndex(@Tags,',',@next),?16);
?????print?@Tag
?????SET?@Next=@Next+1;
?END
?
?
结果为:
111
b2222
323232
32d
e
323232f
g3222