关于oracle的数据导出和导入
2025-09-28 18:02:05以前11g一直使用oracle的exp/imp工具,对空表不导出的问题是使用pl/sql developer的导出用户对象功能,导出sql,在dmp导入后,在执行sql进行补漏.
可能是之前项目表少,数据量也相对少,这样操作的速度和效果都还可以接受.
但最近项目有3百多张表,每个表字段也很多,exp导出就很慢,而且会报错
EXP-00008: ORACLE error 1455 encounteredORA-01455: converting column overflows integer datatype
搜索原因和解决方法,原因有很多,
但是最彻底的解决方法都是推荐使用 oracle新出的数据泵工具,即expd/impd,
试了一下,确实速度快,功能也多.
但是有两个点会直接限制他的使用:
1.如果你的数据库账号 不是DBA角色,那基本是用不了的,因为这两个工具是运行在服务器,要对服务器目录进行读写
2.生成的文件还是在服务器上,如果想下载到本机,或转移到其他服务器,那你需要有这个服务器的相关账号和权限,
当然有一个曲线的办法,不过要求你数据库能与目标数据库连通,就是建一个database links,然后执行impd
总结:如果整个项目是自己的,拥有完全控制权,那非常合适;
如果你只是从别人那里获取了一个数据库的普通权限账号,那是用不了的.
考虑其他解决方案:
1.导出为sql,使用工具如DBeaver或者Oracle官方的sql developer导出速度都比较快
导入相对慢,需要进行优化,deepseek给出的优化方案:
创建一个新的命令文件 import_optimized.sql:
SET ECHO OFF
SET FEEDBACK OFF
SET VERIFY OFF
SET TERMOUT OFF -- 关闭输出,节省时间
SET ARRAYSIZE 10000 -- 增大每次获取的行数
SET LINESIZE 10000
ALTER SESSION FORCE PARALLEL DML; -- 强制并行 DML
ALTER SESSION SET COMMIT_WRITE = 'BATCH, NOWAIT'; -- 优化提交方式
SPOOL import.log
-- 在文件开头:禁用约束和触发器
BEGIN
FOR c IN (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' DISABLE CONSTRAINT ALL';
END LOOP;
END;
/
-- 禁用触发器(可选,如果数据已经清洁)
ALTER TRIGGER ALL DISABLE;
-- 开始导入数据
@your_original_data_file.sql -- 这里执行你的巨大SQL文件
-- 在文件末尾:手动提交,并重新启用约束和触发器
COMMIT;
BEGIN
FOR c IN (SELECT table_name FROM user_tables) LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' ENABLE CONSTRAINT ALL';
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error enabling constraints on ' || c.table_name || ': ' || SQLERRM);
-- 继续执行,不要因为一个表失败而停止
END;
END LOOP;
END;
/
ALTER TRIGGER ALL ENABLE;
SPOOL OFF
然后使用 SQL*Plus 执行这个优化后的脚本:
sqlplus -s username/password@target_db @import_optimized.sql
但是这里有个问题:如果表含有blob,clob等字段,是无法用sql导出的,还是得用imp导出
2.再一种方法就是把表分成几组导出,比如每次50张,然后就是将参数[统计信息]设为无,即STATISTICS=NONE