今天做数据处理的时候遇到一个问题,就是要把一个表A中的某个字段的数据经过处理以后再插入到表B中。一开始用到的是游标,不过最后发现速度跟本不行,执行半天还没完
A表中有800万数据。
具体的逻辑是这样的,就是A表中有一个字段type,这个type中有多个值,其中是以,号隔开的。比如:010,030,020.
现在的情况是我要把A表中的type字段中的值拿出来然后以,号隔开,变成010  030 020 三个值,然后作为三条记录放到表B的字段type 中。在B表中记录会是这样
id  type
1    010
2    030
3    020
三条记录。
存储过程是这样
程序代码:type cur is ref cursorv_resultset cur;
v_resultset1 cur;
v_type varchar2(10);
v_type2 varchar2(30);
open  v_resultset for select type from A;
loop
fetch v_resultset into v_type;
    open resultset1 for select * from table( split(v_type,','));--split是自己写的函数,分隔字符串后得到的是一个集合,还得循环
    loop
       fetch resultset1 into v_type2;
        insert into B values(v_type2);
        close resutlset1;
      end loop;
      close resultset2;
end loop;
commit;
exception
  处理
就是这样,速度异常的慢。不过小北刚接触oracle存储过程,不知道有没有其它的好的实现方式。先谢谢大家了。像上面这个是循环套循环,速度一定会慢的。但是自己实在是想不到有没有更好的解决办法了。希望有经验的大大们不吝赐教!先谢谢了 

解决方案 »

  1.   

    不需要内层循环
    type cur is ref cursorv_resultset cur;
    v_resultset1 cur;
    v_type varchar2(10);
    v_type2 varchar2(30);
    open  v_resultset for select type from A;
    loop
         fetch v_resultset into v_type;
         exit when  v_resultset%notfound;
         insert into B select * from table( split(v_type,','));
    end loop;
    close resultset; --关闭游标放在外面
    commit;
    exception
      处理
      

  2.   


    对了,忘了说清了B表中还需要A表中的ID。不只是类型的。。
    也就是说B表中的记录是这样的
    ID                TYPE
    A表中记录的ID     该ID对应的TYPE
    比如:
    10032             010
    10032             030
    10032             020type cur is ref cursorv_resultset cur;
    v_resultset1 cur;
    v_type varchar2(10);
    v_type2 varchar2(30);
    v_ID  number;
    open  v_resultset for select ID,type from A;
    loop
    fetch v_resultset into v_ID,v_type;
        open resultset1 for select * from table( split(v_type,','));--split是自己写的函数,分隔字符串后得到的是一个集合,还得循环
        loop
           fetch resultset1 into v_type2;
            insert into B values(v_ID,v_type2);
            close resutlset1;
          end loop;
          close resultset;
    end loop;
    commit;
    exception
      处理
    不好意思,刚写错了。我改下
      

  3.   

    可以用Bulk collect and bulk insert 试试
      

  4.   


    type table_b is table of b%rowtype INDEX BY BINARY_INTEGER;
    v_table_b table_b;
    begin 
    select * bulk collect into v_table_b
      from table( split(v_type,','));--
      forall i in 1..v_table_b.count
      insert into insert into B values v_table_b(i);
      commit;
    exception
    ....
    end
      

  5.   


    --改成下面的写法试试
    begin
    for rec in(select type from A)
    loop
      insert into B(id,type)
        select level,regexp_substr(rec.type,'[^,]+',1,level)
          from dual
          connect by level <= length(type)-length(replace(type,',',''));
    end loo;
    commit;
    end;
      

  6.   

    --如果b上有索引,先删除索引,插完再重新创建
    INSERT /*+append*/ INTO b nologging
      SELECT a.id, column_value, '1'
        FROM A,
             TABLE(CAST(MULTISET
                        (SELECT regexp_substr(A.TYPE, '[^,]+', 1, LEVEL)
                           FROM dual
                         CONNECT BY LEVEL <= length(A.TYPE) -
                                    length(REPLACE(A.TYPE, ',')) + 1) AS
                        ty_str_split));