一次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 link
to_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 key
FROM user_constraints
WHERE constraint_type = 'R'
AND status = 'ENABLED') LOOP
EXECUTE 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 constraints
FROM user_constraints
WHERE status = 'ENABLED') LOOP
EXECUTE 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 as
select * 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: 试图创建, 变更或删除正在使用的临时表中的索引
declare
v_table_name varchar2(32);
v_sql varchar2(2000);
v_cnt number; cursor cur is
select t.TABLE_NAME
from user_tables t
where t.TABLE_NAME
in (select st.table_name
from user_tab_columns st
where st.DATA_TYPE in ('CLOB', 'BLOB'))
order by t.TABLE_NAME; begin for i in cur loop
v_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 then
execute 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; exception
when others then
dbms_output.put_line(v_table_name || ':' || sqlcode || ':' || sqlerrm); end get_data_from168;
之后测试了一下,
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?
declare
v_table_name varchar2(32);
v_sql varchar2(2000);
v_cnt number; cursor cur is
select t.TABLE_NAME
from user_tables t
where t.TABLE_NAME
in (select st.table_name
from user_tab_columns st
where st.DATA_TYPE in ('CLOB', 'BLOB'))
order by t.TABLE_NAME; begin for i in cur loop
v_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 then
execute 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 table1
as' || '
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; exception
when others then
dbms_output.put_line(v_table_name || ':' || sqlcode || ':' || sqlerrm); end get_data_from168;
后来想想,如果用Kettle的话会更方便,结果用Kettle测试了一下,Kettle对于lob字段处理的也非常好。

之后Kettle会自动生成每个表对应的转换。
测试运行也没什么问题,非常方便。
一次Oracle数据迁移的更多相关文章
- Oracle数据迁移至HBase操作记录
Oracle数据迁移至HBase操作记录 @(HBase) 近期需要把Oracle数据库中的十几张表T级别的数据迁移至HBase中,过程中遇到了许多苦难和疑惑,在此记录一下希望能帮到一些有同样需求的兄 ...
- Oracle数据迁移expdp/impdp
Oracle数据迁移expdp/impdp目的:指导项目侧自行进行简单的数据泵迁移工作. 本文实验环境:Oracle 11.2.0.4,利用数据库自带的scott示例用户进行试验测试. 1.首先需要创 ...
- Oracle数据迁移至MySQL
ORACLE DB: 11.2.0.3.0 MYSQL DB: 5.5.14 因项目需求,需要将ORACLE生产中数据迁移至MYSQL数据库中作为初始数据,方法有如下几种: 1.ORACLE OGG ...
- Oracle数据迁移笔记-Rownum与序列的自增长的组合用法技巧
Rownum与序列的自增长的组合用法技巧 根据序列自增长的步长规律,结合表行记录Rownum值的规则批量生成表的行记录主键的用法技巧 案例如下: CREATE OR REPLACE PROCEDURE ...
- oracle数据迁移之Exp和Expdp导出数据的性能对比与优化
https://wangbinbin0326.github.io/2017/03/31/oracle%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB%E4%B9%8BExp%E ...
- Oracle数据迁移后由列的直方图统计信息引起的执行计划异常
(一)问题背景 在使用impdp进行数据导入的时候,往往在导入表和索引的统计信息的时候,速度非常慢,因此我在使用impdp进行导入时,会使用exclude=table_statistics排除表的统计 ...
- 【Oracle 数据迁移】环境oracle 11gR2,exp无法导出空表的表结构【转载】
今天做数据迁移,但是发现有些空表无法exp,后来找到问题所在. [原文]:http://www.cnblogs.com/wenlong/p/3684230.html 11GR2中有个新特性,当表无数据 ...
- Oracle数据迁移-系统数据合并笔记
创建临时表:execute immediate 'sql'; 通过临时表和关联查询解决循环处理效率低下,大数据操作移植时时间太长的问题. 结构相同的系统数据库表移植,案例如下: create or r ...
- oracle数据迁移
通过这个文章演示一下Oracle的表空间迁移流程以及需要注意的诸多事项. 实验目标:将ora10g数据库实例上的表空间TBS_SEC_D迁移到secooler数据库实例上操作系统:Redhat 5.3 ...
- oracle 数据迁移之数据泵的基本使用
oracle相同数据库下跨schema的表迁移—expdp/impdp 需求:将GUIDO用户下的表迁移到SCOTT用户下 select * from dba_role_privs where GRA ...
随机推荐
- wcf-1
1.WCF是什么? WindowsCommunication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,由.NET Framework 3. ...
- emplace_back与push_back的区别
std::vector::emplace_back C++ Containers library std::vector template< class... Args &g ...
- TOP30专访:捕鱼达人陈昊芝
原文:http://www.csdn.net/article/2012-04-04/313919/1 编者按:3月31日,第四届CocoaChina游戏开发者大会暨Cocos2D-X技术研讨会在北京举 ...
- nginx rewrite 参数和例子
http://www.cnblogs.com/analyzer/articles/1377684.html ] 本位转自:http://blog.c1gstudio.com/archives/434 ...
- WinServer 之 发布WebService后调用出现" The test form is only available for requests from the local machine. "
当您尝试从远程计算机访问 Web 服务时,不会显示“调用”按钮.并且,您会收到以下错误信息: The test form is only available for requests from the ...
- JForum 2.19源码部署到eclipse
前两天在研究免费论坛,通过oschina和相关的文档查阅,最终选择了jforum,首先他是java写的,其次方便二次开发,而且有些论坛的源码都已经不在维护了,jforum最近几个月还是有更新的,但是从 ...
- Android 开发中的屏幕适配技术详解
本文主要介绍Android开发中比较头疼繁琐的一个问题-屏幕适配问题.主要从适配原因.基本核心概念.适配方法等方面介详细 介绍从而是的深入或者进一步对Android屏幕适配技术的掌握和理解. 真题园网 ...
- 利用android studio gsonformat插件快速解析复杂json
在android开发过程中,难免会遇到json解析,在这篇文章中为你快速解析复杂的json. 首先,在android studio中安装gsonformat插件. 点击File->Setting ...
- 《Mysql 公司职员学习篇》 第二章 小A的惊喜
第二章 小A的惊喜 ---- 认识数据库 吃完饭后,小Y和小A回到了家里,并打开电脑开始学习Mysql. 小Y:"小A,你平时的Excell文件很多的情况下,怎么样存放Exce ...
- Linux系统上安装软件(ftp服务器)
一:安装ftp服务器 在安装linux系统的时候,自定义软件包安装时,我已经勾选了ftp服务器,所以已经 安装过了,如果没有勾选,需要额外下载ftp的安装包,进行安装. ftp服务器搭建过程中遇到的问 ...