今天做数据处理的时候遇到一个问题,就是要把一个表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存储过程,不知道有没有其它的好的实现方式。先谢谢大家了。像上面这个是循环套循环,速度一定会慢的。但是自己实在是想不到有没有更好的解决办法了。希望有经验的大大们不吝赐教!先谢谢了
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存储过程,不知道有没有其它的好的实现方式。先谢谢大家了。像上面这个是循环套循环,速度一定会慢的。但是自己实在是想不到有没有更好的解决办法了。希望有经验的大大们不吝赐教!先谢谢了
解决方案 »
- ebs11.0如何在form定义一个Global变量传参数给report?
- mysql导入到oracle表名过长
- ORACLE 8,如何大量数据在不同表空间移动?
- ado 读取oracle number型字段的问题
- 求救,找回被pl/sql developer drop的存储过程
- 请问谁有metalink的帐号,能否帮忙查查ora-00600[1153][15]错误的解释
- 将文本导入ORACLE数据库时,报错
- 将本地oracle数据导出到另一台机子的oracle里怎么做?
- 以系统管理员身份登陆的问题
- 请各位看一下这个绑定变量的问题?
- ORA-01031:权限不足求教
- ora-12523错误,但是监听和net服务正常。
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
处理
对了,忘了说清了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
处理
不好意思,刚写错了。我改下
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
--改成下面的写法试试
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;
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));