网站首页 > 技术文章 正文
文中使用的Oracle版本为11g。
最近由于开发需要,需要将现生产环境数据库全部同步到开发环境中(包括数据、表结构、存储过程、方法......)。但是在导入的过程中发现了以下问题:
数据库服务端编码不一致,导入之后数据为乱码。表中存在Blob和Clob类型的字段,在导入过程中出现了表不能导入或者导入后没有数据的情况。
由于数据来源是生产库且不能随意访问,因此所有生产数据都将通过脚本晚上定时执行远程备份(脚本是之前同事留下的,离职后没有人维护又将这个烂摊子给到自己头上了)。
在查阅脚本后发现,导出的dmp文件是直接通过exp导出,没有使用到expdp(数据泵),因此在导入时需要做一些特殊处理才能完全导入,共7步下面将进行详细说明。
1 开发库中采用dba账号登录,将当前账号下的所有表描述及其字段描述导出到excel中
导出字段描述语句:
select 'comment on column '||table_name||'.'||column_name||' is '''||comments||''';'
from dba_col_comments t
where t.owner = 'xxx';
导出表描述语句:
select 'comment on table '||table_name||' is '''||comments||''';'
from dba_tab_comments t
where t.owner = 'xxx';
查询结果可以使用PL/SQL的“Copy to Excel...”导出到Excel,如下图:
2 将生产导出的dmp文件上传到导入环境服务器,然后导出当前dmp的结构信息
imp <xe_username>/<password>@XE file=<filename.dmp> indexfile=index.sql full=y
通过上面的语句会将dmp文件中的结构信息导出成一个sql文件,里面的内容大致如下:
3 用PL/SQL打开sql文件,执行以下5步替换操作
找到: 'REM ' 替换: ''找到: '"原来的表空间"' 替换: '"目标表空间"'找到: '...' 替换: 'REM ...'找到: 'CONNECT' 替换: 'REM CONNECT'找到: 'REM ' 替换: '--'
完成操作后执行该脚本,数据库就能够生成好表结构了。
4 执行存储过程干掉所有约束
exec MANAGE_USER_CONSTRAINTS('disable',true,true,true);
存储过程代码如下:
CREATE OR REPLACE PROCEDURE MANAGE_USER_CONSTRAINTS(OPERATION VARCHAR2,
FK BOOLEAN DEFAULT TRUE,
PK BOOLEAN DEFAULT TRUE,
UK BOOLEAN DEFAULT TRUE) IS
/**
启动和关闭约束的存储过程脚本
created by yuanzh 2015-10-22
*/
ST VARCHAR2(255);
--获取外键关系
CURSOR R IS SELECT TABLE_NAME, CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'R';
--获取主键
CURSOR P IS SELECT TABLE_NAME, CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'P' AND INSTR(CONSTRAINT_NAME,'BIN') = 0;
--获取唯一索引
CURSOR U IS SELECT TABLE_NAME, CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'U';
BEGIN
--如果参数中是disable,关闭约束的情况下
IF UPPER(OPERATION) IN ('DROP', 'DISABLE') THEN
--先执行外键约束的关闭
IF FK THEN
FOR E IN R LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
--执行主键约束的关闭
IF PK THEN
-- 先关闭外键
FOR E IN R LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
--再关闭主键
FOR E IN P LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
--执行唯一约束的关闭
IF UK THEN
FOR E IN U LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
--若是启用约束的时候
ELSIF UPPER(OPERATION) IN ('ENABLE') THEN
--先启用主键
IF PK THEN
FOR E IN P LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
--启用外键
IF FK THEN
--先主键启动
FOR E IN P LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
--在外键启动
FOR E IN R LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
--启用唯一约束
IF UK THEN
FOR E IN U LOOP
BEGIN
ST := 'ALTER TABLE ' || E.TABLE_NAME || ' ' || OPERATION || ' CONSTRAINT ' || E.CONSTRAINT_NAME;
EXECUTE IMMEDIATE (ST);
EXCEPTION WHEN OTHERS THEN
NULL;
DBMS_OUTPUT.PUT_LINE(ST);
END;
END LOOP;
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE('THE FIRST PARAMETER OF THE PROCEDURE MUST BE DROP OR ENABLE OR DISABLE');
END IF;
END;
5 执行imp导入
imp xxx/abc@se file=xxx220151020_235000.dmp fromuser=fuser touser=tuser ignore=y grants=n constraints=n rows=y buffer=80000000
6 导入完成之后再重新执行刚才的存储过程开启约束
exec MANAGE_USER_CONSTRAINTS('enable',true,true,true);
7 返回第一点中数据提取的excel,将里面的脚本在Command窗口下执行即可
猜你喜欢
- 2024-11-07 Oracle 脏数据名称解析 oracle脏读
- 2024-11-07 Python 进行 Oracle 与 Mysql 不同数据库类型之间的数据 diff
你 发表评论:
欢迎- 617℃几个Oracle空值处理函数 oracle处理null值的函数
- 610℃Oracle分析函数之Lag和Lead()使用
- 599℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 595℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 591℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 582℃【数据统计分析】详解Oracle分组函数之CUBE
- 572℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 560℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- PageHelper - 最方便的 MyBatis 分页插件
- 面试二:pagehelper是怎么实现分页的,
- MyBatis如何实现分页查询?(mybatis-plus分页查询)
- SpringBoot 各种分页查询方式详解(全网最全)
- 如何在Linux上运行exe文件,怎么用linux运行windows软件
- 快速了解hive(快速了解美国50个州)
- Python 中的 pyodbc 库(pydbclib)
- Linux搭建Weblogic集群(linux weblogic部署项目步骤)
- 「DM专栏」DMDSC共享集群之部署(一)——共享存储配置
- 故障分析 | MySQL 派生表优化(mysql pipe)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)