数据牵移,存储过程的学习(mysql到oracle)

    技术2026-05-27  6

    最近项目中牵涉到把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;

     

     

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

    最新回复(0)