码迷,mamicode.com
首页 > 数据库 > 详细

Oracle sqlldr 应用

时间:2015-03-30 20:30:19      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

我们可以用Oracle的sqlldr工具来导入数据,着重关注以下几个参数:

userid -- Oracle 的 username/password[@servicename]
control -- 控制文件,可能包含表的数据
log -- 记录导入时的日志文件,默认为 控制文件(去除扩展名).log
bad -- 坏数据文件,默认为 控制文件(去除扩展名).bad
data -- 数据文件,一般在控制文件中指定。用参数控制文件中不指定数据文件更适于自动操作
errors -- 允许的错误记录数,可以用他来控制一条记录都不能错
rows -- 多少条记录提交一次,默认为 64
skip -- 跳过的行数,比如导出的数据文件前面几行是表头或其他描述

有两种使用方法:

(1)使用一个控制文件(作为模板) 和一个数据文件

一般为了利于模板和数据的分离,以及程序的不同分工会使用第一种方式,下面是一个比较完整的例子:

OPTIONS (skip=1,rows=128) -- sqlldr 命令显示的选项可以写到这里边来,skip=1 用来跳过数据中的第一行
LOAD DATA
INFILE "users_data.csv" --指定外部数据文件,可以写多个 INFILE "another_data_file.csv" 指定多个数据文件
--这里还可以使用 BADFILE、DISCARDFILE 来指定坏数据和丢弃数据的文件,
truncate --操作类型,用 truncate table 来清除表中原有记录
INTO TABLE users -- 要插入记录的表
Fields terminated by "," -- 数据中每行记录用 "," 分隔
Optionally enclosed by " -- 数据中每个字段用 ‘"‘ 框起,比如字段中有 "," 分隔符时
trailing nullcols --表的字段没有对应的值时允许为空
(
  virtual_column FILLER, --这是一个虚拟字段,用来跳过由 PL/SQL Developer 生成的第一列序号
  user_id number, --字段可以指定类型,否则认为是 CHARACTER 类型, log 文件中有显示
  user_name,
  login_times,
  last_login DATE "YYYY-MM-DD HH24:MI:SS" -- 指定接受日期的格式,相当用 to_date() 函数转换
)

其中append为数据装载方式,还有其他选项:    
  a、insert,为缺省方式,在数据装载开始时要求表为空    
  b、append,在表中追加新记录    
  c、replace,删除旧记录(用 delete from table 语句),替换成新装载的记录    
  d、truncate,删除旧记录(用 truncate table 语句),替换成新装载的记录  

(2)只使用一个控制文件,在这个控制文件中包含数据

把 users_data.cvs 中的内容补到 users.ctl 中,并以 BEGINDATA 连接,还要把 INFILE "users_data.csv" 改为 INFILE *。同时为了更大化的说明问题,把数据处理了一下。此时,完整的 users.ctl 文件内容是:

OPTIONS (skip=1,rows=128) -- sqlldr 命令显示的选项可以写到这里边来,skip=1 用来跳过数据中的第一行
LOAD DATA
INFILE *  -- 因为数据同控制文件在一起,所以用 * 表示
append    -- 这里用了 append 来操作,在表 users 中附加记录 
INTO TABLE users
when LOGIN_TIMES<>8  -- 还可以用 when 子句选择导入符合条件的记录
Fields terminated by ","
trailing nullcols
(
  virtual_column FILLER, --跳过由 PL/SQL Developer 生成的第一列序号
  user_id "user_seq.nextval", --这一列直接取序列的下一值,而不用数据中提供的值
  user_name "Hi ||upper(:user_name)",--,还能用SQL函数或运算对数据进行加工处理
  login_times terminated by ",", NULLIF(login_times=NULL) --可为列单独指定分隔符
  last_login DATE "YYYY-MM-DD HH24:MI:SS" NULLIF (last_login="NULL") -- 当字段为"NULL"时就是 NULL
)
BEGINDATA --数据从这里开始
   ,USER_ID,USER_NAME,LOGIN_TIMES,LAST_LOGIN
1,1,Unmi,3,2009-1-5 20:34
2,2,Fantasia,5,2008-10-15
3,3,隔叶黄莺,8,2009-1-2
4,4,Kypfos,NULL,NULL
5,5,不知秋,1,2008-12-23

逐一举例说明:

1、普通装载

注:BEGINDATA后的数值前面不能有空格

LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY , OPTIONALLY ENCLOSED BY "  
(DEPTNO,
 DNAME,
 LOC
)
BEGINDATA
10,Sales,"""USA"""
20,Accounting,"Virginia,USA" 
30,Consulting,Virginia
40,Finance,Virginia
50,"Finance","",Virginia --loc 列将为空
60,"Finance",,Virginia   --loc 列将为空

 2、TERMINATED BY WHITESPACE 和 FIELDS TERMINATED BY x‘20‘ 的情况 

注:x‘20‘表示字符ASCII码的16进制数值 

LOAD DATA  
INFILE *  
INTO TABLE DEPT  
REPLACE  
FIELDS TERMINATED BY WHITESPACE  
--FIELDS TERMINATED BY x‘20‘  
(DEPTNO,  
 DNAME,  
 LOC  
)
BEGINDATA  
10 Sales Virginia

 3、指定不装载那一列

LOAD DATA  
INFILE *  
INTO TABLE DEPT  
REPLACE  
FIELDS TERMINATED BY , OPTIONALLY ENCLOSED BY "  
(DEPTNO,  
 FILLER_1 FILLER,  --下面的 "Something Not To Be Loaded" 将不会被装载  
 DNAME,  
 LOC  
)  
BEGINDATA  
20,Something Not To Be Loaded,Accounting,"Virginia,USA"

4、position的列子

结果:10 | Accounting Vir | ginia,USA | 10Accounting Virginia,USA

LOAD DATA  
INFILE *  
INTO TABLE DEPT  
REPLACE  
(DEPTNO position(1:2),  
 DNAME position(*:16), --这个字段的开始位置在前一字段的结束位置  
 LOC position(*:29),  
 ENTIRE_LINE position(1:29)  
)  
BEGINDATA 
10Accounting Virginia,USA

5、使用函数日期的一种表达TRAILING NULLCOLS的使用

注:可以通过:dname类型调用函数,特别注意date函数的使用。

LOAD DATA  
INFILE *  
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ,
TRAILING NULLCOLS
--这句的意思是将没有对应值的列都置为null
--如果第一行改为 10,Sales,Virginia,1/5/2000,, 就不用TRAILING NULLCOLS了  
(DEPTNO,  
 DNAME "upper(:dname)", --使用函数  
 LOC "upper(:loc)",  
 LAST_UPDATED date dd/mm/yyyy, --日期的一种表达方式。还有‘dd-mon-yyyy‘等
 ENTIRE_LINE ":deptno||:dname||:loc||:last_updated"  
)  
BEGINDATA  
10,Sales,Virginia,1/5/2000  
20,Accounting,Virginia,21/6/1999  
30,Consulting,Virginia,5/1/2000  
40,Finance,Virginia,15/3/2001  

6、合并多行记录为一行记录

注:例如有些文本文件以N行为一循环记录数据,则可以这样导入。

LOAD DATA  
INFILE *  
concatenate 3 --通过关键字concatenate 把几行的记录看成一行记录  
INTO TABLE DEPT  
replace  
FIELDS TERMINATED BY ,  
(DEPTNO,  
 DNAME "upper(:dname)",  
 LOC "upper(:loc)",  
 LAST_UPDATED date dd/mm/yyyy 
)  
BEGINDATA  
10,Sales,
Virginia,
1/5/2000

7、使用continueif来合并记录行

上例可直接使用continueif last= ‘,‘来告诉Oracle如果前一个数据以‘,‘结尾,则这个附加到上一行

注:ContinueIf还可以使用this或next选项

LOAD DATA  
INFILE *  
continueif last= ,
INTO TABLE DEPT  
replace  
FIELDS TERMINATED BY ,  
(DEPTNO,  
 DNAME "upper(:dname)",  
 LOC "upper(:loc)",  
 LAST_UPDATED date dd/mm/yyyy 
)  
BEGINDATA  
10,Sales,
Virginia,
1/5/2000

8、载入每行的行号

LOAD DATA  
INFILE *  
INTO TABLE DEPT 
replace  
(DEPTNORECNUM //载入每行的行号  
 ENTIRE_LINE Position(1:1024)
)  
BEGINDATA  
fsdfasj     --自动分配行号到DEPTNO字段,此行为1  
fasdjfasdfl --自动递增,此行为2

9、载入有换行符的数据

①使用一个非换行符的字符

注:换行的特殊字符如果使用‘\n‘,则会在Windows编译过程中直接换成换行符,导致无法转换

LOAD DATA  
INFILE *  
INTO TABLE DEPT  
REPLACE  
FIELDS TERMINATED BY ,  
TRAILING NULLCOLS  
(DEPTNO,  
DNAME "upper(:dname)",  
LOC "upper(:loc)",  
LAST_UPDATED "my_to_date( :last_updated )",  
COMMENTS "replace(:comments,%%,chr(10))"  --用replace函数转换成换行符  
)  
BEGINDATA  
10,Sales,Virginia,01-april-2001,This is the Sales%%Office in Virginia  
20,Accounting,Virginia,13/04/2001,This is the Accounting%%Office in Virginia  
30,Consulting,Virginia,14/04/2001 12:02:02,This is the Consulting%%Office in Virginia  
40,Finance,Virginia,987268297,This is the Finance%%Office in Virginia  

②使用fix属性

注:fix只能加在外部文件数据导入时,另外需要每行数据长度都相等。

Load DATA  
INFILE demo1.dat "fix 68"  
INTO TABLE t1_a  
REPLACE  
FIELDS TERMINATED BY ,  
TRAILING NULLCOLS  
(DEPTNO,  
DNAME "upper(:dname)",  
LOC "upper(:loc)",  
LAST_UPDATED Date dd/mm/yyyy,
ENTIRE_LINE  
)
demo1.dat  
10,aaaab,Virginia,01/05/2001,This is the aaaab
Office in Virginia
20,aaaac,Virginia,13/04/2001,This is the aaaac
Office in Virginia
30,aaaad,Virginia,14/04/2001,This is the aaaad
Office in Virginia
40,aaaae,Virginia,16/02/2001,This is the aaaae
Office in Virginia

③ 使用var属性

Load DATA  
INFILE demo17.dat "var 3"  
INTO TABLE t1_a  
REPLACE  
FIELDS TERMINATED BY , 
TRAILING NULLCOLS  
(DEPTNO,  
 DNAME "upper(:dname)",  
 LOC "upper(:loc)",  
 LAST_UPDATED Date dd/mm/yyyy,
 ENTIRE_LINE  
)
demo17.dat  
03510,Sales,Virginia,01/01/2001,This
03920,Accounting,Virginia,13/04/2001,Thi
04530,Consulting,Virginia,14/04/2001,This is t
07140,Finance,Virginia,14/04/2001,This is the Finance Office
 in Virginia
注:var 3 表示前三位用于说明该条记录的长度 (但是谁告诉我长度怎么数的?-_-|||)

④使用str属性
可使用str来定义一个行结尾符
计算以|\r\n 结束的值:
select utl_raw.cast_to_raw(‘|‘||chr(13)||chr(10)) from dual;
结果 7C0D0A

注意:同样需要在外部文件数据导入中使用,且最后一个不用加;另外注意不要有空格

Load DATA  
INFILE demo17.dat "str X7C0D0A"  
INTO TABLE t1_a  
REPLACE  
FIELDS TERMINATED BY ,  
TRAILING NULLCOLS  
(DEPTNO,  
 DNAME "upper(:dname)",  
 LOC "upper(:loc)",  
 LAST_UPDATED Date dd/mm/yyyy,
 ENTIRE_LINE  
)  
demo17.dat  
10,Sales,Virginia,01/01/2001,This is the Sales  
Office in Virginia|
20,Accounting,Virginia,13/04/2001,This is the Accounting  
Office in Virginia|
30,Consulting,Virginia,14/04/2001,This is the Consulting  
Office in Virginia|
40,Finance,Virginia,14/04/2002,This is the Finance  
Office in Virginia

10、nullif导入

注:需要注意的是在前面指定的数据类型以及后面的引号!

LOAD DATA
INFILE *
INTO TABLE t1_a
REPLACE
(DEPTNO position(1:2) integer external nullif DEPTNO=1,
 -- 当导入deotno的值为‘1‘时,则该条记录不导入
 DNAME position(3:8)
)
BEGINDATA
1 10
20lg

 

 

 

 

Oracle sqlldr 应用

标签:

原文地址:http://www.cnblogs.com/abelwang/p/4378688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!