Bootstrap

SQL 拆分字符串

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

转载于:https://www.cnblogs.com/sunbird69/archive/2007/11/18/963364.html

;