一次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 ...
随机推荐
- android123 zhihuibeijing 新闻中心-新闻 页签 ViewPagerIndicator实现
## ViewPagerIndicator ## 使用导入ViewPagerIndicator库的方式相当于可以改源码,打包编译Eclips可以自动完成. ViewPager指针项目,在使用ViewP ...
- div 显示滚动条的CSS代码
div 显示滚动条的CSS代码 div显示上下左右滚动条 <div style="width:260px;height:120px; overflow:scroll; border ...
- Model
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace iFlytekDemo ...
- C#_delegate - Pair<T> & 简单顺序逆序 & 方法委托(在Pair类下)&枚举类型 混搭使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- js数组定义和获取其长度
1.只有值组成的数组,必须先定义数组对象. 定义 var arrs=new array()或 var arrs=[]; 赋值: arrs[]="he";arrs[]="c ...
- Jquery的$命名冲突
在Jquery中,$是JQuery的别名,所有使用$的地方也都可以使用JQuery来替换,如$('#msg')等同于JQuery('#msg')的写法.然而,当我们引入多个js库后,在另外一个js库中 ...
- hunnu 11313 无重复元素序列的最长公共子序列转化成最长递增子序列 求法及证明
题目:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11313 湖师大的比赛,见我的另一篇水题题解,这里要说的 ...
- 通过scrollerview自定义collectionview(常用于推荐关注界面)
最近项目上要实现一个效果,先把效果图摆上来吧: 刚看到效果图的时候 我觉得很简单 用UICollectionview就可以了 但是后来发现collectionview只有两种布局方式 比较单一 ...
- [Doc ID 1666646.1]如何使用功能管理员清除缓存?
文档内容 目标 解决方案 适用于: Oracle iProcurement - 版本 11.5.1 到 12.0.0 [发行版 11.5 到 12] 本文档所含信息适用于所有平台 目标 怎样通 ...
- git 版本控制系统初学
Git -The stupid content tracker, 傻瓜内容跟踪器,是一个由Linux内核开发者Linus为了更好地管理Linux内核开发而创立的分布式版本控制软件. 1.建立本地git ...