在给文章加自定义标签时,需要在存储过程中对输入的字符串按照“,”字符分割成一个字符数组。但是Sql中没有实现字符串分组的Split方 法。因此就需要编写一个自定义的Split函数。我首先是使用表值函数的方法实现的字符串分组,但是在使用中感觉不是很方便。后来又在网上找到了一种使用 两个标量函数,其中一个函数首先返回分割后字符数组的长度,另一个函数依次返回每个分割出的字符串。然后使用循环依次获取分割的字符。
表值函数实现Split方法
1
Create FUNCTION [dbo].[SplitToTable]
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函数返回分割后的字符数组的长度。
1
Create function [dbo].[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函数是按顺序分别获取分割后的字符串。
1
ALTER function [dbo].[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。
1
DECLARE @Tags nvarchar(max
); 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