侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

抽取oracle数据到mysql数据库的实现过程

数据库  /  管理员 发布于 8年前   212

在oracle数据库迁移至mysql数据库,除了oracle数据库模型移到mysql外,还一个重要环节就是要将oracle数据库的数据移到mysql数据库,本人尝试用过多款数据迁移程序,性能都不是很好的,于是自己动手写一个针对于oracle数据库数据迁移到mysql数据程序,其具体过程如下:

1、要抽取mysql表、字段及过滤条件的配制文件imp_data.sql

2、建立一个目录ETL_DIR

3、运行oracle数据库程序P_ETL_ORA_DATA,生成各表的csv数据文件,同时也生成一个导入mysql的脚本文件imp_data.sql

4、导入mysql数据,文件内容如下

load data infile "alarm_hist_inc.csv" into table alarm_hist_inc fields terminated by "," enclosed by "^" lines terminated by "\r\n";load data infile "button_authority.csv" into table button_authority fields terminated by "," enclosed by "^" lines terminated by "\r\n";load data infile "c3_sms_hist_inc.csv" into table c3_sms_hist_inc fields terminated by "," enclosed by "^" lines terminated by "\r\n";load data infile "datapermisson.csv" into table datapermisson fields terminated by "," enclosed by "^" lines terminated by "\r\n";

附:数据库脚本P_ETL_ORA_DATA

CREATE OR REPLACE PROCEDURE P_ETL_ORA_DATA(  P_ORA_DIR  VARCHAR2,  P_DATA_PATH VARCHAR2) IS  TYPE T_REC IS RECORD(    TBN VARCHAR2(40),    WHR VARCHAR2(4000));  TYPE T_TABS IS TABLE OF T_REC;  V_TABS   T_TABS := T_TABS();  V_ETL_DIR  VARCHAR2(40) := P_ORA_DIR;  V_LOAD_FILE UTL_FILE.FILE_TYPE;  PROCEDURE ETL_DATA  (    P_SQL_STMT VARCHAR2,    P_DATA_PATH VARCHAR2,    P_TB_NAME  VARCHAR2  ) IS  BEGIN    DECLARE      V_VAR_COL  VARCHAR2(32767);      V_NUM_COL  NUMBER;      V_DATE_COL DATE;      V_TMZ    TIMESTAMP;      V_COLS   NUMBER;      V_COLS_DESC DBMS_SQL.DESC_TAB;      V_ROW_STR  VARCHAR2(32767);      V_COL_STR  VARCHAR2(32767);      V_SQL_ID  NUMBER;      V_SQL_REF  SYS_REFCURSOR;      V_EXP_FILE UTL_FILE.FILE_TYPE;      V_DATA_PATH VARCHAR2(200);    BEGIN      V_DATA_PATH := P_DATA_PATH;      IF REGEXP_SUBSTR(V_DATA_PATH, '\\$') IS NULL      THEN        V_DATA_PATH := V_DATA_PATH || '\';      END IF;      V_DATA_PATH := REPLACE(V_DATA_PATH, '\', '\\');      OPEN V_SQL_REF FOR P_SQL_STMT;      V_SQL_ID := DBMS_SQL.TO_CURSOR_NUMBER(V_SQL_REF);      DBMS_SQL.DESCRIBE_COLUMNS(V_SQL_ID, V_COLS, V_COLS_DESC);      FOR I IN V_COLS_DESC.FIRST .. V_COLS_DESC.LAST      LOOP        CASE          WHEN V_COLS_DESC(I).COL_TYPE IN (1, 9, 96) THENDBMS_SQL.DEFINE_COLUMN(V_SQL_ID, I, V_VAR_COL, 32767);          WHEN V_COLS_DESC(I).COL_TYPE = 2 THENDBMS_SQL.DEFINE_COLUMN(V_SQL_ID, I, V_NUM_COL);          WHEN V_COLS_DESC(I).COL_TYPE = 12 THENDBMS_SQL.DEFINE_COLUMN(V_SQL_ID, I, V_DATE_COL);          WHEN V_COLS_DESC(I).COL_TYPE = 180 THENDBMS_SQL.DEFINE_COLUMN(V_SQL_ID, I, V_TMZ);        END CASE;      END LOOP;      DECLARE        V_FLUSH_OVER PLS_INTEGER := 1;        V_FILE_OVER PLS_INTEGER := 1;        V_FILE_NO  PLS_INTEGER := 1;        V_FILE_NAME VARCHAR2(200);        V_LINE    VARCHAR2(400);      BEGIN        WHILE DBMS_SQL.FETCH_ROWS(V_SQL_ID) > 0        LOOP          IF V_FILE_OVER = 1          THENV_FILE_NAME := P_TB_NAME || '_' || V_FILE_NO || '.csv';V_EXP_FILE := UTL_FILE.FOPEN(V_ETL_DIR, V_FILE_NAME, OPEN_MODE => 'w', MAX_LINESIZE => 32767);          END IF;          V_ROW_STR := '';          FOR I IN 1 .. V_COLS          LOOPV_COL_STR := '\N';BEGIN  CASE    WHEN V_COLS_DESC(I).COL_TYPE IN (1, 9, 96) THEN      DBMS_SQL.COLUMN_VALUE(V_SQL_ID, I, V_VAR_COL);      IF V_VAR_COL IS NOT NULL      THEN        V_COL_STR := '^' || V_VAR_COL || '^';      END IF;    WHEN V_COLS_DESC(I).COL_TYPE = 2 THEN      DBMS_SQL.COLUMN_VALUE(V_SQL_ID, I, V_NUM_COL);      IF V_NUM_COL IS NOT NULL      THEN        V_COL_STR := V_NUM_COL;      END IF;    WHEN V_COLS_DESC(I).COL_TYPE = 12 THEN      DBMS_SQL.COLUMN_VALUE(V_SQL_ID, I, V_DATE_COL);      IF V_DATE_COL IS NOT NULL      THEN        V_COL_STR := '^' || TO_CHAR(V_DATE_COL, 'yyyy-mm-dd hh24:mi:ss') || '^';      END IF;    WHEN V_COLS_DESC(I).COL_TYPE IN (180, 181, 231) THEN      DBMS_SQL.COLUMN_VALUE(V_SQL_ID, I, V_TMZ);      IF V_TMZ IS NOT NULL      THEN        V_COL_STR := '^' || TO_CHAR(V_TMZ, 'yyyy-mm-dd hh24:mi:ss.ff6') || '^';      END IF;  END CASE;  IF I = 1  THEN    V_ROW_STR := V_COL_STR;  ELSE    V_ROW_STR := V_ROW_STR || ',' || V_COL_STR;  END IF;END;          END LOOP;          UTL_FILE.PUT_LINE(V_EXP_FILE, CONVERT(V_ROW_STR, 'UTF8'));          IF V_FILE_OVER > 200000 /*每200000条记录就产生一个新的文件*/          THENV_FILE_OVER := 1;V_FLUSH_OVER := 1;V_FILE_NO  := V_FILE_NO + 1;UTL_FILE.FCLOSE(V_EXP_FILE);V_LINE := 'load data infile "' || V_DATA_PATH || V_FILE_NAME || '" into table ' || P_TB_NAME;V_LINE := V_LINE || ' fields terminated by "," enclosed by "^" lines terminated by "\r\n";';UTL_FILE.PUT_LINE(V_LOAD_FILE, V_LINE);UTL_FILE.FFLUSH(V_LOAD_FILE);CONTINUE;          END IF;          V_FILE_OVER := V_FILE_OVER + 1;          IF V_FLUSH_OVER > 2000 /*每2000条记录就刷新缓存,写到文件中 */          THENUTL_FILE.FFLUSH(V_EXP_FILE);V_FLUSH_OVER := 1;          ELSEV_FLUSH_OVER := V_FLUSH_OVER + 1;          END IF;        END LOOP;        DBMS_SQL.CLOSE_CURSOR(V_SQL_ID);        IF UTL_FILE.IS_OPEN(V_EXP_FILE)        THEN          UTL_FILE.FCLOSE(V_EXP_FILE);          V_LINE := 'load data infile "' || V_DATA_PATH || V_FILE_NAME || '" into table ' || P_TB_NAME;          V_LINE := V_LINE || ' fields terminated by "," enclosed by "^" lines terminated by "\r\n";';          UTL_FILE.PUT_LINE(V_LOAD_FILE, V_LINE);          UTL_FILE.FFLUSH(V_LOAD_FILE);        END IF;      END;    EXCEPTION      WHEN OTHERS THEN        IF DBMS_SQL.IS_OPEN(V_SQL_ID)        THEN          DBMS_SQL.CLOSE_CURSOR(V_SQL_ID);        END IF;        IF UTL_FILE.IS_OPEN(V_EXP_FILE)        THEN          UTL_FILE.FCLOSE(V_EXP_FILE);        END IF;        DBMS_OUTPUT.PUT_LINE(SQLERRM);        DBMS_OUTPUT.PUT_LINE(P_SQL_STMT);    END;  END;BEGIN  BEGIN    EXECUTE IMMEDIATE 'create table mysql_etl_tbs(tn varchar2(40),cn varchar2(40),ci number) ';  EXCEPTION    WHEN OTHERS THEN      NULL;  END;  EXECUTE IMMEDIATE 'truncate table mysql_etl_tbs';  DECLARE    V_CI    PLS_INTEGER;    V_CN    VARCHAR2(40);    V_ETL_COLS VARCHAR2(32767);    V_TBN   VARCHAR2(30);    V_ETL_CFG VARCHAR2(32767);    V_CNF_FILE UTL_FILE.FILE_TYPE;    V_FROM_POS PLS_INTEGER;  BEGIN    V_CNF_FILE := UTL_FILE.FOPEN(V_ETL_DIR, 'ETL_TABS.CNF', 'r', 32767);    LOOP      UTL_FILE.GET_LINE(V_CNF_FILE, V_ETL_CFG, 32767);      V_FROM_POS := REGEXP_INSTR(V_ETL_CFG, 'from', 1, 1, 0, 'i');      V_ETL_COLS := SUBSTR(V_ETL_CFG, 1, V_FROM_POS - 1);      V_ETL_COLS := REGEXP_SUBSTR(V_ETL_COLS, '(select)(.+)', 1, 1, 'i', 2);      V_TBN   := REGEXP_SUBSTR(V_ETL_CFG, '(\s+from\s+)(\w+)(\s*)', 1, 1, 'i', 2);      V_TBN   := UPPER(V_TBN);      V_TABS.EXTEND();      V_TABS(V_TABS.LAST).TBN := V_TBN;      V_TABS(V_TABS.LAST).WHR := REGEXP_SUBSTR(V_ETL_CFG, '\s+where .+', 1, 1, 'i');      V_CI := 1;      LOOP        V_CN := REGEXP_SUBSTR(V_ETL_COLS, '\S+', 1, V_CI);        EXIT WHEN V_CN IS NULL;        V_CN := UPPER(V_CN);        EXECUTE IMMEDIATE 'insert into mysql_etl_tbs(tn,cn,ci) values(:1,:2,:3)'          USING V_TBN, V_CN, V_CI;        COMMIT;        V_CI := V_CI + 1;      END LOOP;    END LOOP;  EXCEPTION    WHEN UTL_FILE.INVALID_PATH THEN      DBMS_OUTPUT.PUT_LINE('指定的目录:ETL_DIR"' || '"无效!');      RETURN;    WHEN UTL_FILE.INVALID_FILENAME THEN      DBMS_OUTPUT.PUT_LINE('指定的文件:" ETL_TABS.CNF' || '"无效!');      RETURN;    WHEN NO_DATA_FOUND THEN      UTL_FILE.FCLOSE(V_CNF_FILE);    WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE(SQLERRM);      RETURN;  END;  DECLARE    V_CUR_MATCH  SYS_REFCURSOR;    V_SQL_SMT   VARCHAR2(32767);    V_TN     VARCHAR2(40);    V_CN     VARCHAR2(40);    V_CI     PLS_INTEGER;    V_COLUMN_NAME VARCHAR2(40);    V_ETL_COLS  VARCHAR2(32767);    V_LINE    VARCHAR2(4000);    V_TBN     VARCHAR2(40);  BEGIN    V_LOAD_FILE := UTL_FILE.FOPEN(V_ETL_DIR, 'load_data.sql', OPEN_MODE => 'w', MAX_LINESIZE => 32767);    FOR T_IX IN V_TABS.FIRST .. V_TABS.LAST    LOOP      V_SQL_SMT := 'select tn,cn,column_name,ci from ( select * from mysql_etl_tbs where tn='':tbn:'' ) l left join user_tab_columns r on l.tn = r.table_name and l.cn= r.column_name order by ci';      V_TBN   := V_TABS(T_IX).TBN;      V_SQL_SMT := REPLACE(V_SQL_SMT, ':tbn:', V_TBN);      V_ETL_COLS := NULL;      OPEN V_CUR_MATCH FOR V_SQL_SMT;      LOOP        FETCH V_CUR_MATCH          INTO V_TN, V_CN, V_COLUMN_NAME, V_CI;        EXIT WHEN V_CUR_MATCH%NOTFOUND;        IF V_CI > 1        THEN          V_ETL_COLS := V_ETL_COLS || ' , ';        END IF;        IF V_COLUMN_NAME IS NULL        THEN          V_ETL_COLS := V_ETL_COLS || ' cast(null as number) ' || V_CN;        ELSE          V_ETL_COLS := V_ETL_COLS || V_CN;        END IF;      END LOOP;      CLOSE V_CUR_MATCH;      V_TBN   := LOWER(V_TBN);      V_SQL_SMT := 'select ' || V_ETL_COLS || ' from ' || V_TBN || V_TABS(T_IX).WHR;      ETL_DATA(V_SQL_SMT, P_DATA_PATH, V_TBN);    END LOOP;    IF UTL_FILE.IS_OPEN(V_LOAD_FILE)    THEN      UTL_FILE.FCLOSE(V_LOAD_FILE);    END IF;  END;END P_ETL_ORA_DATA;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接


  • 上一条:
    详解Mysql数据库date, datetime类型设置0000-00-00默认值(default)报错问题
    下一条:
    mysql如何利用Navicat导出和导入数据库的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客