日期:2014-05-17  浏览次数:20842 次

大量数据从A表转移到B表的存储过程,使用事务。
问题是这样的:数据库中有A(id,typeid,publishDate)表和(id,typeid,publishDate)表,结构是一样的,由于A表中的数据太大,并且多数数据不使用了,故想把它当中的部分数据转移到B表中。
A表中的类型有type1、type2和type3三种类型,转移的要求是类型记录数大于1000条的(按发布时间(publishdate)降序排列)的数据(即当类型的记录数小于1000条就不用转移)。
由于数据量太大,所以使用转移一条到B表后,再删除A表那条数据,使用事务保证数据的正确转移。
求实现此功能的存储过程。

------解决方案--------------------
insert into b select * from a m where (select count(*) from a n where m.publishDate> n.publishDate and m.typeid=n.typeid)> =1000;--不包含1000
------解决方案--------------------
delete from a m where (select count(*) from a n where m.publishDate> n.publishDate and m.typeid=n.typeid)> =1000;--不包含1000
------解决方案--------------------
错了,应该是小于才是降序.
insert into b select * from a m where (select count(*) from a n where m.publishDate <n.publishDate and m.typeid=n.typeid)> =1000;--不包含1000
delete from a m where (select count(*) from a n where m.publishDate <n.publishDate and m.typeid=n.typeid)> =1000;--不包含1000

------解决方案--------------------
不知是否符合搂主的要求,transaction是按每一个typeid来做的,如果中间失败,会回滚出异常的那个typeid,不会影响别的typeid。
用记事本写的,没有跑过,如有细微错误如拼写错误等,请搂主自己修改吧。
另,请将Output功能打开。
procedure move_data
is pragma autonomous_transaction;
begin
for rec_data in (
select typeid as type id,
count(1) as record_count
from a)
loop
begin
set savepoint sp_each_loop;
if rec_data.record_count > 1000 then
insert into b
select * from a
where rownum > 1000
order by a.publishDate desc;

delete b
where rownum > 1000
order by b.publishDate desc;

commit;
dbms_output.put_line( 'Move data of typeid: ' || rec_data.typeid || ' successfully! ');
end if;
dbms_output.put_line( 'Records of typeid: ' || rec_data.typeid || ' is less than 1000. ');
exception
when others then
rollback to sp_each_loop;
dbms_output.punt_line( 'Error occured when processing typeid: ' || rec_data.typeid || '. ');
end;
end loop;
exception
when others then
dbms_output.put_line(substr(sqlerrm, 1, 4000));
end;