每月新增數據百萬多條,需要定期處理2個主要數據表(test_ad,test_pd),移動非當月數據到歷史表中保存
數據操作存儲過程如下:
MYPROC.prc
create or replace procedure MYPROC is
TableName_AD char(13);
TableName_PD char(13);
tmp_str varchar2(100);
tmp_str2 varchar2(100);
tmp_str3 varchar2(100);
tmp_str4 varchar2(100);
tmp_str5 varchar2(100);
tmp_str6 varchar2(100);
tmp_str7 varchar2(100);
tmp_str8 varchar2(100);
begin
--臨時表名賦值
if TableName_AD is null then
select 'PA_AD_'||to_char(add_months(sysdate,-1),'yyyymm') into TableName_AD from dual;
end if;
if TableName_PD is null then
select 'PA_PD_'||to_char(add_months(sysdate,-1),'yyyymm') into TableName_PD from dual;
end if;
--創建(test_ad)歷史表
tmp_str:='create table '||TableName_AD||' as select * from test_ad where patroldate<'''||to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyy-mm-dd'),'yyyy-mm-dd')||'''';
execute immediate tmp_str;
--創建(test_pd)歷史表
tmp_str2:='create table '||TableName_PD||' as select * from test_pd where patroldate<'''||to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyy-mm-dd'),'yyyy-mm-dd')||'''';
execute immediate tmp_str2;
--commit;
--創建本月數據臨時表
tmp_str3:='create table temp_ad as select * from test_ad Where patroldate > ='''||to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyymmdd'),'yyyymmdd')||'''';
execute immediate tmp_str3;
tmp_str4:='create table temp_pd as select * from test_pd Where patroldate > ='''||to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyymmdd'),'yyyymmdd')||'''';
execute immediate tmp_str4;
--刪除本月數據表(test_ad,test_pd)
tmp_str5:='drop TABLE test_ad';
execute immediate tmp_str5;
tmp_str6:='drop TABLE test_pd';
execute immediate tmp_str6;
--本月數據臨時表重命名表(test_ad,test_pd)
tmp_str7:='rename temp_ad to test_ad';
tmp_str8:='rename temp_pd to test_pd';
execute immediate tmp_str7;
execute immediate tmp_str8;
/*--刪除主數據表上非本月記錄
delete from test_ad where patroldate<to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyymmdd'),'yyyymmdd');
--刪除歷史表本月記錄
delete from test_pd where patroldate<to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyymmdd'),'yyyymmdd');
--刪除歷史表本月記錄
tmp_str2:='delete from '||tmp_TableName||' where patroldate>='||to_date(to_char(add_months(last_day(sysdate) +1,-1),'yyyymmdd'),'yyyymmdd');
execute immediate tmp_str2;
*/
--插入操作記錄
insert into oper_proc_log values(sysdate,'pc',0);
commit;
end MYPROC;
--=============注意!在存儲過程中使用CREATE或DROP需要顯示授權==========
--grant create table to user,grant drop any table to user
/
注:上面有一段被注釋的內容,是最初的方案,但是後來了解到:刪除大量數據,Oracle並不釋放空間!所以用了現在的方案,復制創建表——>刪除表——>重命名。
以上存儲過程每月3號定期執行
declare job1 number;
begin
--每月3號午夜12點執行MYPROC
dbms_job.submit(job1,'MYPROC;',sysdate,'TRUNC(LAST_DAY(SYSDATE ) + 3)');
commit;
end;
為了補救意外導致3號午夜12點沒有執行MYPROC
使用另外一個存儲過程驗證MYPROC是否執行
PASUPPLYPROC.prc
create or replace procedure PASUPPLYPROC is
isnull integer;
tmp_str varchar2(100);
begin
--取得本月執行myproc次數
if isnull is null then
select count(*) into isnull from oper_proc_log
where oper_date>=to_date(to_char(add_months(last_day(sysdate) +1,-1), 'yyyymmdd'),'yyyymmdd');
end if;
--無本月執行記錄則立即執行myproc
if isnull=0 then
tmp_str:='begin myproc; end;';
execute immediate tmp_str;
commit;
end if;
end PASUPPLYPROC;
--=============注意!在存儲過程中使用CREATE或DROP需要顯示授權==========
--grant create table to user,grant drop table to user
/
第二個job定期執行PASUPPLYPROC驗證
declare job1 number;
begin
--每月15號午夜12點10分執行PASUPPLYPROC
dbms_job.submit(job1,'PASUPPLYPROC;',sysdate,'TRUNC(LAST_DAY(SYSDATE) + 14) +(24*60+10)/(24*60)');
commit;
end;