拆分字符串

/**//*
问题描述:分隔字符串,大都用临时表或表变量,有时候要在存储过程里用到,又在循环里采用此种方式就会成为性能的颈瓶,
现在采用 charindex 函数解决这个问题。
*/
--
if object_id(N'DivStr') is not null
begin
drop table DivStr;
end
-- 创建测试表
create table DivStr
(
id int not null identity(1,1) ,
Iname nvarchar(200),
PNo nvarchar(500)
)
-- 填充测试数据,现在为 700 行,假设每个数据行不同的情况
declare @a int
select @a = 0
while @a < 100 -- 可以修改之后再运行
begin
insert into DivStr
select 'a','a|aa|aaa' + cast(@a as varchar) union all
select 'b','|b|bb|bbb' + cast(@a as varchar) union all
select 'c','c|cc|ccc|' + cast(@a as varchar) union all
select 'd','|d|dd|ddd|' + cast(@a as varchar) union all
select 'e','e||ee|eee' + cast(@a as varchar) union all
select 'f','f||ff|fff|' + cast(@a as varchar) union all
select 'g','|g|g||g||' + cast(@a as varchar)
select @a = @a + 1;
end

-- select * from DivStr
-- select count(*) from DivStr

declare @i int -- 控制循环变量
declare @c int -- 循环次数
declare @p int -- 查找字符串位置
declare @str nvarchar(500) -- 动态执行字符串
declare @pnostr nvarchar(500) -- 每行取的数据串
declare @pnostrtemp nvarchar(500) -- 拆分字符串时临时变量
declare @pno nvarchar(100) -- 拆分之后的单个字符串

select @i = 0,@p = 0 -- 初值
select @c = count(*) from DivStr -- 循环次数值

-- print @c

while @i < @c
begin
declare @ii int -- 控制内层循环
declare @cc int -- 内层循环次数
select @ii = 0,@str = 'select @pnostr = PNo from DivStr
where id =' + str(@i)
-- print @str
exec sp_executesql @str,N'@pnostr nvarchar(500) output',@pnostr output -- 取每行数据
select @pnostr = '''' + replace(@pnostr,'|',''',''') + '''' -- 转换 | -> ','
select @pnostr = replace(@pnostr,''''',','') -- 过滤 '', 注: 最前面有'|'
select @pnostr = replace(@pnostr,',''''','') -- 过滤 ,'' 注: 最后面有'|'
select @pnostr = replace(@pnostr,'''''','') -- 过滤 '' 注: 连续||的情况
select @i = @i + 1,@cc = len(@pnostr) - len(replace(@pnostr,',','')) + 1
-- print @cc
-- print @pnostr
select @pnostrtemp = @pnostr
while @ii < @cc
begin
select @ii = @ii + 1,@p = charindex(',',@pnostrtemp,@p) -- 第一个,起始位置
-- print @p
if @p = 0
begin
select @pno = @pnostrtemp -- 如果位置为 0,则说明为最后一个字符串
end
else
begin
select @pno = left(@pnostrtemp,@p - 1) -- 否则取第一个','号前的字符串
end
-- print @pno
select @pnostrtemp = right(@pnostrtemp,len(@pnostrtemp) - @p) -- 取第一个','之后的字符串
-- print @pnostrtemp
end
end
posted on
2007-11-18 19:30
sunbird69
阅读(
895)
评论()
收藏
举报