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