/**/
/*
问题描述:分隔字符串,大都用临时表或表变量,有时候要在存储过程里用到,又在循环里采用此种方式就会成为性能的颈瓶,
现在采用 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
![](/Images/OutliningIndicators/None.gif)
--
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
转载于:https://www.cnblogs.com/sunbird69/archive/2007/11/18/963364.html