数据牵移,存储过程的学习(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;

 

 

以上为测试时实现的所有存储过程,都已经通过!

你可能感兴趣的:(数据牵移,存储过程的学习(mysql到oracle))