代码改变世界

SQL 实现 C# Split 功能

2010-08-02 22:00  音乐让我说  阅读(579)  评论(0编辑  收藏  举报

在给文章加自定义标签时,需要在存储过程中对输入的字符串按照“,”字符分割成一个字符数组。但是Sql中没有实现字符串分组的Split方法。因此就需要编写一个自定义的Split函数。我首先是使用表值函数的方法实现的字符串分组,但是在使用中感觉不是很方便。后来又在网上找到了一种使用两个标量函数,其中一个函数首先返回分割后字符数组的长度,另一个函数依次返回每个分割出的字符串。然后使用循环依次获取分割的字符。

 

表值函数实现Split方法:

  

Create FUNCTION [dbo].[SplitToTable]
(
    @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', ',')
--或者select * FROm dbo.SplitToTable('我 是 中国 人', default)
结果为

id          value
----------- ---------------------------------------
1           111
2           b2222
3           323232
4           32d
5           e
6           323232f
7           g3222

(7 行受影响)

 

使用循环的方法

首先GetSplitLength函数返回分割后的字符数组的长度。

Create function [dbo].[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
go

 

结果为:

 

select dbo.GetSplitLength('111,b2222,323232,32d,e,323232f,g3222',',')

结果为7。

 

GetSplitOfIndex函数是按顺序分别获取分割后的字符串。

 

Create function [dbo].[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。

 

比较简单、推荐的方式:

 

DECLARE @Tags nvarchar(max);
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


 

 

 

等待更新...