目标数据库:Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

源数据库  : Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

1.首先想到的是用expdp,impdp。

通过交流发现无法得到源数据库的操作系统密码,这样一来expdp,impdp就不好使了。

2.其次想到的是用plsql developer 来导出数据,但是导出的时候报错了。

放弃此种方法。

3.由于数据量不是很大,考虑使用数据库链的方式来完成。

a.在目标数据库上创建数据库链,链接到目标数据库。

create public database linkto_168_bi22 connect to "bi41" identified by "bi41" using
'(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST =172.21.1.68)(PORT = 1521)))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = orcl)))';

b.得到用户对象的定义语句 dbms_metadata.get_ddl('TABLE','ACT_GE_BYTEARRAY')

在此纠结了一下,是直接用过程脚本来创建表,还是先生成建表语句,之后再循环灌数据。

c.选择先创建用户对象,之后再插入数据。

这个选择给后续的数据插入带来了一些麻烦,就是索引和约束,特别是外键约束。

在脚本中加入了禁用约束的语句

FOR i IN (SELECT table_name, constraint_name --disable first the foreign keyFROM user_constraintsWHERE constraint_type = 'R'AND status = 'ENABLED') LOOPEXECUTE IMMEDIATE 'alter table "' || i.table_name || '" disable constraint ' ||i.constraint_name;END LOOP i;FOR i IN (SELECT table_name, constraint_name -- then disable all constraintsFROM user_constraintsWHERE status = 'ENABLED') LOOPEXECUTE IMMEDIATE 'alter table "' || i.table_name || '" disable constraint ' ||i.constraint_name;END LOOP i;

感觉OK的时候,又报错了。

ERROR:  ORA-22992: cannot use LOB locators selected from remote tables

原来表中有些是LOB字段,无法通过数据链访问直接访问。

最后想到用Oracle的全局临时表的方式将数据抽取过来。

这里也有一个小插曲,就是有50多个表都是有lob字段的。

想写一个循环利用动态SQL来创建global temporary table,并且每次创建之前删除掉改全局临时表。

v_sql := 'create global temporary table table1  ON COMMIT PRESERVE ROWS asselect * from ' || v_table_name;execute immediate v_sql;v_sql := 'insert into table1 ' || 'select * from  ' || v_table_name || '@to_168_bi';execute immediate v_sql;v_sql := 'insert into  ' || v_table_name || 'select * from  table1';execute immediate v_sql;

    commit;

这样创建的临时表默认是 COMMIT delete ROWS 的。

发现数据没有抽取过来,初步怀疑是动态执行SQL的时候自动提交了,这里有些没有想清楚。

之后创建全局临时表的时候加上了ON COMMIT PRESERVE ROWS。

数据是抽过来了,但是drop的时候会报错:ORA-14452: 试图创建, 变更或删除正在使用的临时表中的索引

declarev_table_name varchar2(32);v_sql        varchar2(2000);v_cnt number;cursor cur isselect t.TABLE_NAMEfrom user_tables twhere t.TABLE_NAMEin (select st.table_namefrom user_tab_columns stwhere st.DATA_TYPE in ('CLOB', 'BLOB'))order by t.TABLE_NAME;beginfor i in cur loopv_table_name := i.table_name;v_sql        := 'truncate table ' || v_table_name;execute immediate v_sql;select count(1) into v_cnt from user_tables t where t.TABLE_NAME=upper('table1');if v_cnt >0 thenexecute immediate 'drop table table1';end if; v_sql := 'create global temporary table table1    ON COMMIT PRESERVE ROWS as' || 'select * from  ' || v_table_name ||'@to_168_bi';execute immediate v_sql;v_sql := 'insert into  ' || v_table_name || 'select * from table1';execute immediate v_sql;commit;end loop;exceptionwhen others thendbms_output.put_line(v_table_name || ':' || sqlcode || ':' || sqlerrm);end get_data_from168;

View Code

之后测试了一下,

SQL> create global temporary table table1 as select * from employees;Table created.SQL> drop table table1;Table dropped.SQL> create global temporary table table1 on commit preserve rows as select * from employees;Table created.SQL> drop table table1;
drop table table1*
ERROR at line 1:
ORA-14452: attempt to create, alter or drop an index on temporary table already
in use

实验证明创建glob temporary table 的时候如果添加了on commit preserve rows在session没有退出的情况下是没发drop的。

之后这样写在SQLplus 中执行却没什么问题,plsql developer 的test procedure的方式是多session?

declarev_table_name varchar2(32);v_sql        varchar2(2000);v_cnt number;cursor cur isselect t.TABLE_NAMEfrom user_tables twhere t.TABLE_NAMEin (select st.table_namefrom user_tab_columns stwhere st.DATA_TYPE in ('CLOB', 'BLOB'))order by t.TABLE_NAME;beginfor i in cur loopv_table_name := i.table_name;v_sql        := 'truncate table ' || v_table_name;execute immediate v_sql;select count(1) into v_cnt from user_tables t where t.TABLE_NAME=upper('table1');if v_cnt >0 thenexecute immediate 'drop table table1';end if; /* v_sql := 'create global temporary table table1    ON COMMIT PRESERVE ROWS as' || 'select * from  ' || v_table_name ||'@to_168_bi';execute immediate v_sql;*/v_sql := 'create global temporary table table1as' || 'select * from  ' || v_table_name;execute immediate v_sql;execute immediate ('insert into table1 select * from  '||v_table_name||'@to_168_bi');v_sql := 'insert into  ' || v_table_name || 'select * from table1';execute immediate v_sql;commit;end loop;exceptionwhen others thendbms_output.put_line(v_table_name || ':' || sqlcode || ':' || sqlerrm);end get_data_from168;

View Code

后来想想,如果用Kettle的话会更方便,结果用Kettle测试了一下,Kettle对于lob字段处理的也非常好。

之后Kettle会自动生成每个表对应的转换。

测试运行也没什么问题,非常方便。

转载于:https://www.cnblogs.com/Alex-Zeng/p/3988504.html

一次Oracle数据迁移相关推荐

  1. oracle数据迁移到mysql

    Kettle7.0实现oracle到mysql数据库迁移(批量全量导入) https://blog.csdn.net/j1231230/article/details/80525922 Kettle ...

  2. Oracle数据迁移MySQL

    前言: 现今,Oracle数据迁移MySQL的需求已经越来越普遍,主要的迁移场景大致可以分为三类,第一类是涉及小表以及少量表的一次性迁移,无需进行增量同步,第二类是涉及大表以及多表的一次性迁移,第三类 ...

  3. ORACLE数据迁移参考

    一.ORACLE数据库数据迁移: A.数据迁移方法 1.导入导出方法exp.exe/imp.exe;       优点:兼容性强,可以导出对象可以自定义: 2.数据泵导入导出(oracle10g版本以 ...

  4. oracle迁移至gaussdb,GaussDB for DWS 数据融合系列第九期:Oracle数据迁移到GaussDB(DWS)...

    当客户选择切换到GaussDB(DWS)数据库后可能会面临数据库的迁移任务,数据库迁移包括用户数据迁移和应用程序sql脚本迁移,其中,应用程序sql脚本迁移是一个复杂.高风险且耗时的过程. DSC(D ...

  5. 使用Kettle 进行行Oracle数据迁移时处理编码转换处理US7ASCII 编码

    查看Oracle数据源编码: 执行: SELECT Userenv('language') FROM dual; 结果:AMERICAN_AMERICA.US7ASCII mysql  目标库 为ut ...

  6. Oracle数据迁移 EXP/IMP

    昨天用了这样一个语句来导出数据库文件..导了一会儿就卡死了. full=y是导出整个数据库,不加full=y是导出当前连接数据库的用户下的数据,trainee这个用户没有DBA权限,应该是不能导出整个 ...

  7. 【Oracle 数据迁移】环境oracle 11gR2,exp无法导出空表的表结构【转载】

    今天做数据迁移,但是发现有些空表无法exp,后来找到问题所在. [原文]:http://www.cnblogs.com/wenlong/p/3684230.html 11GR2中有个新特性,当表无数据 ...

  8. 32位oracle数据迁移到64位oracle,将Oracle数据库从32位平台迁移到64位

    3: 查看当前的数据库状态 SQL> select count(*) from dba_objects where status ='INVALID'; COUNT(*) ---------- ...

  9. oracle数据迁移常用

    在数据表间复制数据是Oracle DBA经常面对的任务之一,Oracle为这一任务提供了多种解决方案,SQL*Plus Copy 命令便是其中之一.SQL*Plus Copy 命令通过SQL*Net在 ...

  10. ORACLE 数据迁移

    步骤: 备份数据库 backup database 1.use rman backup database rman target / rman>backup as compressed back ...

最新文章

  1. 分布式锁-常用技术方案
  2. [react] 有用过react的Fragment吗?它的运用场景是什么
  3. 基于ASP.net耳机网店商城系统(前台页面+后台页面)
  4. python电脑编程求圆的面积案例_学Python划重点七 网络编程(UPD Socket编程、上传文件实例、计算圆的面积实例)...
  5. 交叉验证选择最佳参数_如何为您的公司选择最佳的身份验证即服务提供商
  6. 东南大学数字信号处理实验_数字与信号处理实验1 离散时间信号分析
  7. iPhone 11系列没5G又没创新 库克的回应听了真是让人没脾气...
  8. ## CSP 201809-2 买菜(C语言)(100分)
  9. linux下无法创建组
  10. Centos7安装nxlog-2.9
  11. 百战程序员python百度网盘_【百战程序员】Python 文件I/O
  12. Avalondock 第四步 边缘停靠
  13. mmd Ray渲染 mikumikudance导入模型阴影很黑
  14. tplink查看上网记录_Tplink路由器PPPOE拨号不能上网日志查看原因
  15. 景深决定照相机什么特性_浅析决定景深之四大因素
  16. 编写Java脚本统计工程代码总行数
  17. HTML导出生成Word文档
  18. 噩梦射手(SurvivalShooter)教程(十一)
  19. Kotlin学习笔记(二)——函数操作符内置函数
  20. 苹果xr如何截屏_苹果手机如何单手操作截屏

热门文章

  1. UNITY 手游(安卓)如何使用C/C++代码
  2. WHAT IS ERP
  3. SDUT-3378_数据结构实验之查找六:顺序查找
  4. TCP连接的建立(二)
  5. 【NetApp】IO读写和WAFL的工作原理
  6. 【HDOJ】1890 Robotic Sort
  7. javascript继承一览
  8. Siege的线程模型-基于版本2.56
  9. [RDLC]报表根据字段列动态加载图片(二)
  10. DNS服务器详解--------基础篇