环境:linux5.6系统、oracle 11.2.0.2版本
一、准备工作:
1、准备要装载的数据
语言:三个层面要保持一致
(源文件)因为系统的环境变量和数据库的字符集都是UTF8,所以要保证数据源也是UTF8格式。如果不是,可以打开之后另存为一下(选择UTF8)
(数据库)
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8
(系统)
[root@oradb01test arch]# su - oracle
[oracle@oradb01test ~]$ echo $NLS_LANG ----------$NLS_LANG变量一般在vi bashrc中,也有人习惯另外保存
AMERICAN_AMERICA.AL32UTF8
2、格式:由于数据在导出时,数值以加双引号的形式保存的即:
"客户编号","日期","积分","处理类型","处理类型说明","积分类型","积分类型说明"
因此我用sed进行数据清洗sed -i 's/"//g' 20151231.txt
我的数据源保存路径/home/oracle/sqlload/20151231.txt
======================================================================
二、数据库中创建表结构:
CREATE TABLE "KETTLE"."消费明细"
( "客户编号" VARCHAR2(200),
"日期" VARCHAR2(200),
"积分" VARCHAR2(200),
"处理类型" VARCHAR2(200),
"处理类型说明" VARCHAR2(200),
"积分类型" VARCHAR2(200),
"积分类型说明" VARCHAR2(200));
=============================================================================================
二、编辑控制文件
Touch一个文件如20151231.ctl
Vi进去编辑
Load data
CHARACTERSET AL32UTF8 ----指定字符编码
infile '/home/oracle/sqlload/20151231.txt'
append
into table消费明细
fields terminated by ','
(客户编号,日期,积分,处理类型,处理类型说明,积分类型,积分类型说明)
**********************************************************************************************
OPTIONS (skip=1,rows=128) -- sqlldr命令显示的选项可以写到这里边来,skip=1用来跳过数据中的第一行
LOADDATA
infile 指数据源文件 这里我们省略了默认的 discardfile result.dsc badfile result.bad
INFILE‘/home/oracle/sqlload/20151231.txt’ --指定外部数据文件,可以是不同格式的数据文件,如csv、txt都支持 可以写多个INFILE "another_data_file.csv"指定多个数据文件。
into table resultxt默认是INSERT,也可以into table 20151231.txt APPEND为追加方式,或REPLACE
*************以下是4种装入表的方式
APPEND 原先的表有数据就加在后面
INSERT 装载空表如果原先的表有数据 sqlloader会停止默认值
REPLACE 原先的表有数据原先的数据会全部删除
TRUNCATE 指定的内容和replace的相同会用truncate语句删除现存数据
terminatedby ',' 指用逗号分隔
terminated by whitespace 结尾以空白分隔
===============================================================================================
三、导入数据
参数可以再命令行下输入sqlldr查看
有效的关键字:
userid -- ORACLE用户名/口令
control -- 控制文件名
log -- 日志文件名
bad -- 错误文件名
data -- 数据文件名
discard -- 废弃文件名
discardmax -- 允许废弃的文件的数目 (全部默认)
skip -- 要跳过的逻辑记录的数目 (默认 0)
load -- 要加载的逻辑记录的数目 (全部默认)
errors -- 允许的错误的数目 (默认 50)
rows -- 常规路径绑定数组中或直接路径保存数据间的行数
(默认:常规路径 64,所有直接路径)
bindsize -- 常规路径绑定数组的大小 (以字节计) (默认 256000)
silent -- 运行过程中隐藏消息 (标题,反馈,错误,废弃,分区)
direct -- 使用直接路径 (默认 FALSE)
parfile -- 参数文件:包含参数说明的文件的名称
parallel -- 执行并行加载 (默认 FALSE)
file -- 要从以下对象中分配区的文件
skip_unusable_indexes -- 不允许/允许使用无用的索引或索引分区 (默认 FALSE)
skip_index_maintenance -- 没有维护索引,将受到影响的索引标记为无用 (默认 FALSE)
commit_discontinued--提交加载中断时已加载的行 (默认 FALSE)
readsize -- 读取缓冲区的大小 (默认 1048576)
external_table -- 使用外部表进行加载; NOT_USED, GENERATE_ONLY,EXECUTE (默认 NO
T_USED)
columnarrayrows -- 直接路径列数组的行数 (默认 5000)
streamsize -- 直接路径流缓冲区的大小 (以字节计) (默认 256000)
multithreading -- 在直接路径中使用多线程
resumable -- 启用或禁用当前的可恢复会话 (默认 FALSE)
resumable_name -- 有助于标识可恢复语句的文本字符串
resumable_timeout -- RESUMABLE 的等待时间 (以秒计) (默认 7200)
date_cache -- 日期转换高速缓存的大小 (以条目计) (默认 1000)
no_index_errors -- 出现任何索引错误时中止加载 (默认 FALSE)
由于我的数据量大,要求快速导入,因此我的写法如下:
[oracle@oradb01test ~]$sqlldr userid=KETTLE/kettle control=/u01/app/oracle/oradata/oratest/20151231.ctl
log=/u01/app/oracle/oradata/oratest/20151231.log direct=true parallel=true
注:
1、当加载大量数据时(大约超过10GB),最好抑制日志的产生:
SQL>ALTER TABLE 消费明细 nologging;这样不产生REDOLOG,可以提高效率。
2、使用了direct=true,parallel=true两个参数时可能报错:
SQL*Loader-937: parallel load requested and name has enabled triggers or constraints
Cause: A request was made for a parallel direct load, but the object to be loaded has an enabled constraint (check, referential) and/or enabled triggers.
Action: Disable the offending enabled constraints and/or triggers and retry the parallel direct load.
因为对并行的直接路径导入有限制,表中不能有check,referential约束和触发器,所以可以先删掉表中check。
[oracle@oradbsqlload]$sqlldr userid=KETTLE/kettle control=/u01/app/oracle/oradata/oratest/20151231.ctl log=/u01/app/oracle/oradata/20151231.log
SQL*Loader: Release 11.2.0.1.0 - Production on Wed Apr12 10:47:47 2017
Copyright (c) 1982, 2009, Oracle and/or itsaffiliates. All rights reserved.
Load completed - logical record count 2820285.
导入成功!