數據牽移,存儲過程的學習(mysql到oracle)

最近項目中牽涉到把mysql中一個表的數據牽移oracle上來,並只保存三個月的數據,由於此表的數據增加量比較大,現在是每個月三百萬,以後會更多,所

 

以oracle表在實現時考慮到完整的增加與刪除的策略!

下面將記錄再實現過程中所遇到的所有問題:

1.對於數據量的不斷增加,由於跟據時間特性,所以採用按時間進行分區的方式實現

2.對於增加與刪除分區,採用存儲過程來實現,採用定時執行的存儲過程JOB,每月增加與刪除一次分區。

3.對於表字段自增採用序列的方式實現。

4.對於以前數據牽移,在表建好後,一部分數據再建立索引以前牽移,等牽移完整後,切換數據庫,切換成功後再牽移另一部分數據。

 

對於表結構的實現以及存儲過程的建立語法如下:(網上參考別人的方式,實現的)

創建序列:

drop sequence loginid_seq;

create sequence loginid_seq

minvalue 1

nomaxvalue

start with 1

increment by 1

nocache;

 

分區表結構創建:

drop table tb_domainmail_weblogin_log;

CREATE TABLE tb_domainmail_weblogin_log(

  login_id number primary key,

  domain varchar2(100) not null,

  account_name varchar2(50) not null,

  login_type varchar2(20) not null,

  login_time date default sysdate,

  login_ip varchar2(130) default NULL

)

partition by range(login_time) 

(

partition P_weblogin_20100115 values less than(to_date('2010-01-15 12:00:00','YYYY-MM-DD HH24:mi:ss')),--測試所用

partition P_weblogin_20110115 values less than(to_date('2011-01-15 12:00:00','YYYY-MM-DD HH24:mi:ss')),

partition P_weblogin_20110215 values less than(to_date('2011-02-15 12:00:00','YYYY-MM-DD HH24:mi:ss'))

);

--增加一個分區

alter table tb_domainmail_weblogin_log add partition P_weblogin_20110315 values less than(to_date('2011-03-15 12:00:00','YYYY-MM-DD 

 

HH24:mi:ss'));

 

--增加分區的存儲過程

CREATE OR REPLACE PROCEDURE WEBLOGIN_ADD_PARTITION_PROC(

 partNum  NUMBER,  --添加分區的個數

 partDay  NUMBER  --分區之間的時間間隔

) AS

 v_SqlExec VARCHAR2(2000); --DDL語句變量

 v_PartDate VARCHAR2(20); --創建分區的日期(YYYYMMDD)

 v_PartDate1 VARCHAR2(30); --創建分區的日期(YYYYMMDD)

 v_err_num  NUMBER;  --ORA錯誤號

 v_err_msg  VARCHAR2(100); --錯誤描述

 v_PartDate_max VARCHAR2(20); --test_log 表分區的最大日期

BEGIN

--查詢已創建 tb_domainmail_weblogin_log 表分區的最大日期

--P_weblogin_20110215

select max(SUBSTR(partition_name,12,8)) into v_PartDate_max

from user_tab_partitions

WHERE table_name=UPPER('tb_domainmail_weblogin_log');

FOR i IN 1..partNum LOOP

  --創建 tb_domainmail_weblogin_log 表分區

  IF v_PartDate_max<to_char(sysdate+(i*partDay),'yyyymmdd') THEN

  v_PartDate:=to_char(SYSDATE+(i*partDay),'YYYYMMDD');

  v_PartDate1:=to_char(SYSDATE+(i*partDay),'YYYY-MM-DD HH24:mi:ss');

  v_SqlExec:='ALTER TABLE tb_domainmail_weblogin_log ADD PARTITION P_WEBLOGIN_' || v_PartDate ||

   ' values less than (to_date(''' || v_PartDate1 || ''',''YYYY-MM-DD HH24:mi:ss''))';

  dbms_output.put_line('創建 tb_domainmail_weblogin_log 表分區' || i || '='||v_SqlExec);

  DBMS_Utility.Exec_DDL_Statement(v_SqlExec);

  END IF;

 END LOOP;

EXCEPTION

 WHEN OTHERS THEN

  v_err_num := SQLCODE;

  v_err_msg := SUBSTR(SQLERRM, 1, 100);

  dbms_output.put_line('WEBLOGIN_ADD_PARTITION_PROC執行出現異常,錯誤碼='|| v_err_num || '錯誤描述=' || v_err_msg);

END WEBLOGIN_ADD_PARTITION_PROC;

 

--再次,建立刪除分區的存儲過程

CREATE OR REPLACE PROCEDURE WEBLOGIN_DROP_PARTITION_PROC(

 beforeDays NUMBER  --刪除多少天前的分區

)

As

 v_SqlExec  VARCHAR2(2000); --DDL語句變量

 v_err_num  NUMBER;  --ORA錯誤號

 v_err_msg  VARCHAR2(100); --錯誤描述

 --查找beforeDays天前存在的 tb_domainmail_weblogin_log 表分區

 cursor cursor_testlog_part is

 select partition_name from user_tab_partitions

 WHERE table_name=UPPER('tb_domainmail_weblogin_log')

 AND SUBSTR(partition_name,12,8)<TO_CHAR(SYSDATE-beforeDays,'YYYYMMDD')

 ORDER BY partition_name;

 record_testlog_oldpart cursor_testlog_part%rowType;

BEGIN

 open cursor_testlog_part;

  loop

   fetch cursor_testlog_part into record_testlog_oldpart;

   exit when cursor_testlog_part%notfound;

   --刪除 tb_domainmail_weblogin_log 表分區

   v_SqlExec:='ALTER TABLE tb_domainmail_weblogin_log DROP PARTITION ' ||

   record_testlog_oldpart.partition_name;

   dbms_output.put_line('刪除tb_domainmail_weblogin_log表分區='||v_SqlExec);

   DBMS_Utility.Exec_DDL_Statement(v_SqlExec);

  end loop;

 close cursor_testlog_part;

EXCEPTION

 WHEN OTHERS THEN

  v_err_num := SQLCODE;

  v_err_msg := SUBSTR(SQLERRM, 1, 100);

  dbms_output.put_line('WEBLOGIN_DROP_PARTITION_PROC執行出現異常,錯誤碼='|| v_err_num || '錯誤描述=' || v_err_msg);

END WEBLOGIN_DROP_PARTITION_PROC;

/

 

--執行增加的存儲過程:

CREATE OR REPLACE PROCEDURE WEBLOGIN_EXEC_ADD_PROC AS

   v_err_num  NUMBER;  --ORA錯誤號

   v_err_msg  VARCHAR2(100); --錯誤描述

   v_date VARCHAR2(2):='15'; --每個月的15號做此事。

BEGIN

   --2代表創建一個分區,30代表分區大小爲30天的數據。

   IF v_date=to_char(SYSDATE,'DD') THEN

     WEBLOGIN_ADD_PARTITION_PROC(2,'31');

     COMMIT;

   END IF;

EXCEPTION

 WHEN OTHERS THEN

  v_err_num := SQLCODE;

  v_err_msg := SUBSTR(SQLERRM, 1, 100);

  dbms_output.put_line('WEBLOGIN_EXEC_ADD_PROC執行出現異常,錯誤碼='|| v_err_num || '錯誤描述=' || v_err_msg);

END WEBLOGIN_EXEC_ADD_PROC;

 

 

--執行刪除的存儲過程:

CREATE OR REPLACE PROCEDURE WEBLOGIN_EXEC_DROP_PROC AS

   v_err_num  NUMBER;  --ORA錯誤號

   v_err_msg  VARCHAR2(100); --錯誤描述

   v_date VARCHAR2(2):='15'; --每個月的15號做此事。

BEGIN

 --刪除3個月前的數據 100代表100天

  IF v_date=to_char(SYSDATE,'DD') THEN

     WEBLOGIN_DROP_PARTITION_PROC(100);

     COMMIT;

   END IF;

EXCEPTION

 WHEN OTHERS THEN

  v_err_num := SQLCODE;

  v_err_msg := SUBSTR(SQLERRM, 1, 100);

  dbms_output.put_line('WEBLOGIN_DROP_PARTITION_PROC執行出現異常,錯誤碼='|| v_err_num || '錯誤描述=' || v_err_msg);

END WEBLOGIN_EXEC_DROP_PROC;

 

--建立JOB定時執行存儲過程

create or replace procedure WEBLOGIN_JOBS_PROC as

    job1 number;  --每個月15號18點創建分區

    job2 number;  --每個月15號23點刪除分區  

    v_err_num  NUMBER;  --ORA錯誤號

    v_err_msg  VARCHAR2(100); --錯誤描述

begin

    dbms_job.submit(job1,'WEBLOGIN_EXEC_ADD_PROC;',sysdate,'SYSDATE + (18*60)/(24*60)');

    dbms_job.submit(job2,'WEBLOGIN_EXEC_DROP_PROC;',sysdate,'SYSDATE + (23*60)/(24*60)');

 commit;

EXCEPTION

 WHEN OTHERS THEN

  v_err_num := SQLCODE;

  v_err_msg := SUBSTR(SQLERRM, 1, 100);

  dbms_output.put_line('WEBLOGIN_JOBS_PROC執行出現異常,錯誤碼='|| v_err_num || '錯誤描述=' || v_err_msg);

end WEBLOGIN_JOBS_PROC;

 

-執行定時工作JOB存儲過程

execute WEBLOGIN_JOBS_PROC;

--刪除存儲過程

drop PROCEDURE WEBLOGIN_JOBS_PROC;

execute WEBLOGIN_EXEC_ADD_PROC;

 

 

以上爲測試時實現的所有存儲過程,都已經通過!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章