一次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 ...
随机推荐
- android125 zhihuibeijing 缓存
## 三级缓存 ## - 内存缓存, 优先加载, 速度最快 - 本地缓存(内存卡), 次优先加载, 速度快 - 网络缓存, 不优先加载, 速度慢,浪费流量 package com.itheima.zh ...
- C 二叉树
二叉树表示法 P127页 /* typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTre ...
- yum -------包安装库
elrepo: http://elrepo.org/tiki/tiki-index.php CentOSPlus: http://wiki.centos.org/zh/AdditionalR ...
- 9个使用前必须再三小心的Linux命令
Linux shell/terminal 命令非常强大,即使一个简单的命令就可能导致文件夹.文件或者路径文件夹等被删除.在一些情况下,Linux 甚至不会询问你而直接执行命令,导致你丢失各种数据信 ...
- mysql performance schema的即时诊断工具-邱伟胜
https://github.com/noodba http://www.noodba.com
- 大设计时代:针对超大网页布局的一些思考和建议 [Aseoe]
对于有些设计项目来说,老套的设计模式并不奏效,你需要设计的大点,要比以往设计的元素还要大,因此就非常适合采用超大网页布局.无论是采用大块大块的背景照片还是背景视频,超大网页布局的效果非常显著:极具视觉 ...
- APP运营干货分享
从移动互联网市场总监岗位出发,从几个方面来阐述移动互联网部门如何制定一份运营推广策划案,至于关于移动互联网,移动电商是大趋势这些虚的.空泛的文字,不展开说了. 一.竞品分析 1.选择竞品,做好定位(选 ...
- 深入浅出ECharts系列 (二) 折线图
深入浅出ECharts系列(二) 目标 本次教程的目标是实现“折线图堆叠”折线,实现结果如图: 2. 准备工作 a) 首先下载ECharts插件,你可以根据自己的实际需求选择你想要下载 ...
- 轻松学习Ionic (二) 为Android项目集成Crosswalk(更新官方命令行工具)
现在集成crosswalk不用这么麻烦了!官方的命令行工具已经能让我们一步到位,省去很多工作,只需在cmd中进入项目所在目录(不能有中文目录,还得FQ),执行: ionic browser a ...
- 第四章 jQuery中的事件
1.加载DOM jQuery中,在$(document).ready()方法内注册的事件,只要DOM就绪就会被执行,此时可能元素的关联文件未下载完. jQuery中的 load()方法,会在元素的on ...