--就楼主自己的处理过程而言,本身就有很多不合理的地方
DECLARE @w_no char(7),
@c_no char(8),
@serial char(2),
@attr varchar(60),
@serial_count int,
@i int,
@j int
declare @n int
select @i=1,@n=count(*) from tb1
WHILE @i<=@n --(select count(*) from tb1)
BEGIN
/*
SET @w_no=(select w_no from tb1 where id=@i)
SET @c_no=(select c_no from tb1 where id=@i)
SET @serial=(select serial from tb1 where id=@i)
SET @attr=(select rtrim(attr) from tb1 where id=@i)
SET @serial_count=len(@attr/2)
SET @j=1
*/
--每查一次,就要扫描一次表,其实一次就可以查出来了
select @w_no=w_no,
@c_no=c_no,
@serial=serial,
@attr=rtrim(attr),
@serial_count=len(@attr/2),
@j=1
from tb1 where id=@i

解决方案 »

  1.   

    最关键的是楼主并没有说清楚具体要怎么处理,所以上面的回复也只是解决部分问题.在楼主的代码中,循环分拆更新是检测到一个值就终止当前的分拆搜索,似乎与"如果找到匹配的记录就将tb1中的一些字段更新到tb2中,并且将tb2中的一些字段信息更新到tb1中。"不太符合,是否难保证attr在tb2中只有<=1个匹配的?
      

  2.   

    --如果只是根据楼主给出的代码来改写处理,只需要两个更新语句就OK了,根本不用分拆update b
    set serial_kd=a.serial
    from tb1 a,tb2 b
    where a.w_no=b.w_no 
    and a.c_no=b.c_no 
    and b.pri_tag='V'
    and charindex(b.serial,a.attr)%2=1update a
    set ursach_t_a='T',u_teilenr=b.pnr1+b.pnr2+b.pnr3+b.pnr4+b.pnr5+b.pnr6
    from tb1 a,tb2 b
    where a.w_no=b.w_no 
    and a.c_no=b.c_no 
    and b.pri_tag='V'
    and charindex(b.serial,a.attr)%2=1
      

  3.   

    如果b.serial='11',a.attr='011011',用charindex(b.serial,a.attr)%2=1就会产生错误。
    我的数据库中的attr字符串编排是两位、两位的按照大小排列,但是出现哪两个是不确定的。我刚才试了一下用Fast_forward游标将tb1中的w_no,c_no,attr拆分到一个关系表,和tb1是一对多的关系,5秒就可以完成,然后通过联结更新两个表的内容,好像效率还可以。这样的数据结构是不是很不合理,以前的人设计的,准备在当中加一个关系表。
      

  4.   

    --确实忽略了那个问题,那可以分拆到临时表处理--一次性分拆,效率应该比游标好
    select top 30 id=identity(int,0,1) into # from sysobjects a,sysobjects b
    select a.id,attr=substring(attr,b.id*2+1,2) into #1
    from tb1 a,# b
    where len(attr)/2>=b.id
        and exists( select * from tb2  --这个条件可以初步限制只处理符合条件的数据,这样分拆处理会慢一些,但后面的处理会快一些,是否加上,你可以根据实际情况取舍
    where a.w_no=w_no 
    and a.c_no=c_no 
    and pri_tag='V'
    and charindex(serial,a.attr)>0) update b
    set serial_kd=a.serial
    from tb1 a,tb2 b,#1 aa
    where a.w_no=b.w_no 
    and a.c_no=b.c_no 
    and b.pri_tag='V'
    and b.serial=aa.attr
    and a.id=aa.idupdate a
    set ursach_t_a='T',u_teilenr=b.pnr1+b.pnr2+b.pnr3+b.pnr4+b.pnr5+b.pnr6
    from tb1 a,tb2 b,#1 aa
    where a.w_no=b.w_no 
    and a.c_no=b.c_no 
    and b.pri_tag='V'
    and b.serial=aa.attr
    and a.id=aa.id
    drop table #,#1
      

  5.   

    谢谢邹建大侠,分拆效率是高了很多。
    但是每条记录分拆后会多一条记录,我需要使用 DELETE #1 where attr='' 来删除。
    另外我对这个sql语句还不是很明白,select list里面使用[字段名]=表达式是如何工作的,希望能提供一些例子和参考。
      

  6.   

    --误用了等号,改一下就不存在分拆后多一条记录的问题了.select top 30 id=identity(int,0,1) into # from sysobjects a,sysobjects b
    select a.id,attr=substring(attr,b.id*2+1,2) into #1
    from tb1 a,# b
    where len(attr)/2>b.id  --误用了等号
        and exists( select * from tb2 --这个条件可以初步限制只处理符合条件的数据,这样分拆处理会慢一些,但后面的处理会快一些,是否加上,你可以根据实际情况取舍
    where a.w_no=w_no 
    and a.c_no=c_no 
    and pri_tag='V'
    and charindex(serial,a.attr)>0)