现有三个表  
TBL_A  
ID    //非自增字段  
NAME  
_____________  
TBL_B  
ID    //自增字段  
AID    //对应TBL_A的ID  
NAME  
___________  
TBL_C  
ID    //自增字段  
BID  //对应TBL_B的ID  
NAME  
 
ID均为自增的字段,三个表均有一个与之对应的历史表,符合一定条件的数据会被移动到对应的三个历史表中,TBL_B的ID字段在数据移动后会发生变化,此时要更新TBL_C中相应的BID,现在我采用的是游标,TBL_A中有10000条,对应每条记录B中有10条,C中10条共有22万条记录,此时采用游标已经慢的无法忍受了。  
请问各位有其他什么方法啊。  
 
create  or  replace  procedure  test  
   is  
   m_bid  number;  
   cursor  a_cursor  is  select  id  from  tbl_a  
   a_id  tbl_a.id%type;  
   cursor  b_cursor(m_id  number)  is  select  id  from  tbl_b  where  aid=m_id;  
   b_id  tbl_b.id%type;  
begin  
   open  a_cursor;  
   loop  
       fetch  a_cursor  into  a_id;  
       exit  when  a_cursor;  
         
       insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a);  
         
       open  b_cursor(a_id);  
       loop  
           fetch  b_cursor  into  b_id;  
           exit  when  b_cursor;  
             
           insert  into  tbl_b_history  (name,aid)    (select  name,aid  from  tbl_b  where  id=b_id);  
           select  seq_b.currval  into  m_bid  from  dual;  
           insert  into  tbl_c_history  (name,bid)  (select  name,m_bid  from  tbl_c  where  bid=b_id);  
             
       end  loop;  
       close  b_cursor;  
         
   end  loop;  
   close  a_cursor;  
     
   commit;  
     
   exception  when  others  then  
       rollback;  
end;

解决方案 »

  1.   

    try:
    create  or  replace  procedure  test  
       is  
       m_bid  number;  
    begin  
          
      insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a);  
      select  seq_b.currval  into  m_bid  from  dual;   
      insert  into  tbl_b_history  (name,aid) 
      (select  t.name,t.aid  from  tbl_b t,tbl_a tt where  tt.id=t.aid);  
      insert  into  tbl_c_history  (name,bid)  
      (select  name,m_bid  from  tbl_c  where  bid>m_bid);  
        
       commit;  
         
       exception  when  others  then  
           rollback;  
    end;
    /另外,下面这一段没看懂
    loop
    fetch  a_cursor  into  a_id; //打开游标  
           exit  when  a_cursor;    
           insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a);//重复保存tbl_a的数据???在循环内
    ...
      

  2.   

    我看了一下你的:
    insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a);  
    少了条件"where id=a_id",这样在循环体内这个历史表的记录数暴增...
    修改一下:
    insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a where id=a_id); 
     
      

  3.   

    insert  into  tbl_a_history  (id,name)  (select  id,name  from  tbl_a);这里我本来是有 "where id=a_id"的,是我copy过来改名字的时候弄掉了 :)
      

  4.   

    exit  when  a_cursor;  是exit  when  a_cursor%notfound;  呵呵
      

  5.   

    TO: bzszp(SongZip)你这样不是所有的tbl_c的新记录都把bid改成了m_id
      

  6.   

    不是,
    select  seq_b.currval  into  m_bid  from  dual; --取出插入数据前的序号   
      insert  into  tbl_b_history  (name,aid) --插入数据
      (select  t.name,t.aid  from  tbl_b t,tbl_a tt where  tt.id=t.aid);  
      insert  into  tbl_c_history  (name,bid)  
      (select  name,m_bid  from  tbl_c  where  bid>m_bid); --根据刚刚插入的数据进行处理(注意:是bid>m_bid 取出的是新数据)
      

  7.   

    简单的说 就是A表移动到新表 ID发生变化,此时B表也移动到新表,需将B表中对应的老AID改为新的AID
      

  8.   

    都是移动到新表 所以我就insert时就是新id,但是速度太慢了