在 Oracle 数据库中,通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法:
1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中
2. 建立数据库间的 dblink,然后用 create table B as select * from
A@dblink where ...,或 insert into B select * from A@dblink
where ...
3. exp A 表,再 imp 到 B 表,exp 时可加查询条件
4. 程序实现 select from A ..,然后 insert into B ...,也要分批提交
5. Sql Loader(sqlldr) 导入数据,效果比起逐条 insert 来很明显。
方法一
操作步骤:
用pl/sql developer登陆Oracle,选择工具->Export Tables...->选择需要的表->Export到指定目录
打开cmd命令窗口输入下面语句
imp 用户名/密码@数据库实例名 file=dmp文件存在的目录 log=日志文件存在的目录fromuser=用户名 touser=用户名 commit=y
如:imp system/system@ring218 file=D:\dbscript\usdp\usdp_212.dmp log=D:\imp_usdp_sh.log fromuser=usdp604 touser=usdp604 commit=y
方法二:
Sql Loader导入
eg:
创建一个控制文件(.ctl):
OPTIONS (skip=1,rows=128,errors=100000) --sqlldr 命令显示的选项可以写到这里边来,skip=1 用来跳过数据中的第一行
LOAD DATA
INFILE "users_data.csv" --要导入的文件,可以用多个infile也可以用 * 表示所有
BADFILE "路径" --指定BAD文件存放的路径
insert/append/replace/truncate --默认为insert
INTO TABLE users
when 字段2<>'8' --可以用 when 子句选择导入符合条件的记录
CHARACTER SET utf8 FIELDS TERMINATED BY ','--字符编码
Fields terminated by "," --数据中每行记录用 "," 分隔
--注意:请加上下面一行句子
Optionally enclosed by '"' --数据中每个字段用 '"' 框起,比如字段中有 "," 分隔符时
trailing nullcols
(
字段1 integer,--可以为字段指定类型
字段2 "user_seq.nextval",--直接取序列的下一值
字段3 FILLER,--跳过此字段
字段4 "'Hi '||upper(:字段4)",--用SQL函数或运算对数据进行加工处理
字段5 terminated by ",",NULLIF(字段5='NULL')--为列单独指定分隔符
字段6 DATE "YYYY-MM-DD HH24:MI:SS" NULLIF(字段6="NULL") --当字段为"NULL"时就是 NULL),
字段7 char(1000)--控制文件中的字段默认为char256,超过256需要指定长度,否则Log会报数据文件的字段超出最大长度
注:
1) insert --为缺省方式,在数据装载开始时要求表为空[/color]
2) append --在表中追加新记录[/color]
3) replace --删除旧记录(用 delete from table 语句),替换成新装载的记录
4) truncate --删除旧记录(用 truncate table 语句),替换成新装载的记录
详细参数说明,要着重关注以下几个参数:
userid -- Oracle 的 username/password[@servicename]
control -- 控制文件,可能包含表的数据
----------------------------------------------------------------------log -- 记录导入时的日志文件,默认为 控制文件(去除扩展名).log
bad -- 坏数据文件,默认为 控制文件(去除扩展名).bad
data -- 数据文件,一般在控制文件中指定。用参数控制文件中不指定数据文件更适于自动操作
errors -- 允许的错误记录数,可以用他来控制一条记录都不能错
rows -- 多少条记录提交一次,默认为 64
skip -- 跳过的行数,比如导出的数据文件前面几行是表头或其他描述
SQL *Loader 的性能与并发操作
1) ROWS 的默认值为 64,你可以根据实际指定更合适的 ROWS 参数来指定每次提交记录数。(体验过在 PL/SQL Developer 中一次执行几条条以上的 insert 语句的情形吗?)
2)常规导入可以通过使用 INSERT语句来导入数据。Direct导入可以跳过数据库的相关逻辑(DIRECT=TRUE),而直接将数据导入到数据文件中,可以提高导入数据的性能。当然,在很多情况下,不能使用此参数(如果主键重复的话会使索引的状态变成UNUSABLE!)。
3) 通过指定 UNRECOVERABLE选项,可以关闭数据库的日志(是否要 alter table table1 nologging 呢?)。这个选项只能和 direct 一起使用。
4) 对于超大数据文件的导入就要用并发操作了,即同时运行多个导入任务.
sqlldr userid=/ control=result1.ctl direct=true parallel=true
sqlldr userid=/ control=result2.ctl direct=true parallel=true
sqlldr userid=/ control=result2.ctl direct=true parallel=true
当加载大量数据时(大约超过10GB),最好抑制日志的产生:
SQL>ALTER TABLE RESULTXT nologging;
这样不产生REDO LOG,可以提高效率。然后在 CONTROL 文件中 load data 上面加一行:unrecoverable, 此选项必须要与DIRECT共同应用。
在并发操作时,ORACLE声称可以达到每小时处理100GB数据的能力!其实,估计能到 1-10G 就算不错了,开始可用结构 相同的文件,但只有少量数据,成功后开始加载大量数据,这样可以避免时间的浪费