/**/
/*
问题描述:分隔字符串,大都用临时表或表变量,有时候要在存储过程里用到,又在循环里采用此种方式就会成为性能的颈瓶,
现在采用 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
问题描述:分隔字符串,大都用临时表或表变量,有时候要在存储过程里用到,又在循环里采用此种方式就会成为性能的颈瓶,
现在采用 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