一次Oracle数据迁移
目标数据库: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数据迁移相关推荐
- oracle数据迁移到mysql
Kettle7.0实现oracle到mysql数据库迁移(批量全量导入) https://blog.csdn.net/j1231230/article/details/80525922 Kettle ...
- Oracle数据迁移MySQL
前言: 现今,Oracle数据迁移MySQL的需求已经越来越普遍,主要的迁移场景大致可以分为三类,第一类是涉及小表以及少量表的一次性迁移,无需进行增量同步,第二类是涉及大表以及多表的一次性迁移,第三类 ...
- ORACLE数据迁移参考
一.ORACLE数据库数据迁移: A.数据迁移方法 1.导入导出方法exp.exe/imp.exe; 优点:兼容性强,可以导出对象可以自定义: 2.数据泵导入导出(oracle10g版本以 ...
- oracle迁移至gaussdb,GaussDB for DWS 数据融合系列第九期:Oracle数据迁移到GaussDB(DWS)...
当客户选择切换到GaussDB(DWS)数据库后可能会面临数据库的迁移任务,数据库迁移包括用户数据迁移和应用程序sql脚本迁移,其中,应用程序sql脚本迁移是一个复杂.高风险且耗时的过程. DSC(D ...
- 使用Kettle 进行行Oracle数据迁移时处理编码转换处理US7ASCII 编码
查看Oracle数据源编码: 执行: SELECT Userenv('language') FROM dual; 结果:AMERICAN_AMERICA.US7ASCII mysql 目标库 为ut ...
- Oracle数据迁移 EXP/IMP
昨天用了这样一个语句来导出数据库文件..导了一会儿就卡死了. full=y是导出整个数据库,不加full=y是导出当前连接数据库的用户下的数据,trainee这个用户没有DBA权限,应该是不能导出整个 ...
- 【Oracle 数据迁移】环境oracle 11gR2,exp无法导出空表的表结构【转载】
今天做数据迁移,但是发现有些空表无法exp,后来找到问题所在. [原文]:http://www.cnblogs.com/wenlong/p/3684230.html 11GR2中有个新特性,当表无数据 ...
- 32位oracle数据迁移到64位oracle,将Oracle数据库从32位平台迁移到64位
3: 查看当前的数据库状态 SQL> select count(*) from dba_objects where status ='INVALID'; COUNT(*) ---------- ...
- oracle数据迁移常用
在数据表间复制数据是Oracle DBA经常面对的任务之一,Oracle为这一任务提供了多种解决方案,SQL*Plus Copy 命令便是其中之一.SQL*Plus Copy 命令通过SQL*Net在 ...
- ORACLE 数据迁移
步骤: 备份数据库 backup database 1.use rman backup database rman target / rman>backup as compressed back ...
最新文章
- 分布式锁-常用技术方案
- [react] 有用过react的Fragment吗?它的运用场景是什么
- 基于ASP.net耳机网店商城系统(前台页面+后台页面)
- python电脑编程求圆的面积案例_学Python划重点七 网络编程(UPD Socket编程、上传文件实例、计算圆的面积实例)...
- 交叉验证选择最佳参数_如何为您的公司选择最佳的身份验证即服务提供商
- 东南大学数字信号处理实验_数字与信号处理实验1 离散时间信号分析
- iPhone 11系列没5G又没创新 库克的回应听了真是让人没脾气...
- ## CSP 201809-2 买菜(C语言)(100分)
- linux下无法创建组
- Centos7安装nxlog-2.9
- 百战程序员python百度网盘_【百战程序员】Python 文件I/O
- Avalondock 第四步 边缘停靠
- mmd Ray渲染 mikumikudance导入模型阴影很黑
- tplink查看上网记录_Tplink路由器PPPOE拨号不能上网日志查看原因
- 景深决定照相机什么特性_浅析决定景深之四大因素
- 编写Java脚本统计工程代码总行数
- HTML导出生成Word文档
- 噩梦射手(SurvivalShooter)教程(十一)
- Kotlin学习笔记(二)——函数操作符内置函数
- 苹果xr如何截屏_苹果手机如何单手操作截屏