SQL Loader 学习笔记
一、SQL Loader定义
SQL Loader可以把一些以文本格式存放的数据顺利的导入到oracle数据库中,是一种在不同数据库之间进行数据迁移的非常方便而且通用的工具。通常用来将操作系统文件迁移到ORACLE数据库中。SQL Loader是大型数据仓库选择使用的加载方法,因为它提供了最快速的途径(DIRECT,PARALLEL)。
缺点就速度比较慢,另外对blob等类型的数据就有点麻烦了。
二、SQL Loader用法
在Window系统下,SQLLoader的命令为SQLLDR,在UNIX下一般为sqlldr/sqlload。
用法: SQLLDR keyword=value [,keyword=value,...]
有效的关键字:
???? userid ?? ??????????????? -- ORACLEusername/password?
?? ? control ? ??????????????? -- 控制文件
? log ???????? ??????????????? -- 记录的日志文件
???? bad ??????? ??????????????? -- 坏数据文件,如果有的数据没有被处理,将会出现在这里。
???? data ????? ??????????????? -- 数据文件
?discard ??????????????? -- 丢弃的数据文件
?discardmax ???????? -- 允许丢弃数据的最大值???????(全部默认)
???? skip ??????? ??????????????? -- Number of logical records toskip? (默认0)
???? load ?????? ??????????????? -- Number of logical records toload? (全部默认)
?errors?? ??????????????? –允许的错误记录数?????????(默认50)
?rows ???? ??????????????? -- Number of rows in conventionalpath bind array or between direct path data saves?? (每次提交的记录数,默认:常规路径 64, 所有直接路径)
bindsize ??????????????? -- Size of conventional path bindarray in bytes(默认256000)
???????????????????????????????????? 每次提交记录的缓冲区的大小(字节为单位,默认256000)
silent ???????????????????? -- 禁止输出信息 (header,feedback,errors,discards,partitions)
direct ??????????????????? -- 使用直通路径方式导入???????????????????(默认FALSE)
parfile ?????????????????? -- parameterfile: name of file that contains parameter specifications
parallel ???????????????? -- 并行导入??????????????????(默认FALSE)
file ???????????????????????? -- File toallocate extents from
--与bindsize成对使用,其中较小者会自动调整到较大者。sqlldr先计算单条记录长度,乘以rows,如小于bindsize,不会试图扩张rows以填充bindsize;如超出,则以bindsize为准。
external_table??? ??????????????? -- useexternal table for load; NOT_USED, GENERATE_ONLY, EXECUTE(默认NOT_USED)
columnarrayrows?????????????? -- Number ofrows for direct path column array(默认5000)
streamsize ????????? ??????????????? -- Size of direct path stream bufferin bytes(默认256000)
multithreading??? ??????????????? --use multithreading in direct path
?resumable ????????? ??????????????? -- enable or disable resumable forcurrent session(默认FALSE)
resumable_name?????????????? -- text stringto help identify resumable statement
resumable_timeout?????????? -- wait time(in seconds) for RESUMABLE(默认7200)
date_cache ???????? ??????????????? -- size (in entries) of dateconversion cache(默认1000)
注意:有两种方式可以指定命令行参数:通过位置或者通过关键字。通过位置的例子:'sqlldrscott/tiger test.ctl',通过关键字的例子:'sqlldr userid=scott/tiger?control=testlog=test.log';但是不能前面使用关键字指定后面通过位置制定的混合方式;为清楚起见最好所有命令行参数都用关键字指定。
三、SQL Loader实例
控制文件的写法:
示例一:
一个控制命令的脚本文件,通常以ctl结尾,内容如下:
LOAD ???DATA
INFILE????????? 't.dat'??????????????????? 要导入的文件
// INFILE???? 'tt.date' ??????????????? ??????????????? 导入多个文件
// INFILE*?????????表示要导入的内容就在control本文件里;下面的BEGINDATA后面就是导入的内容
INTO ?TABLE ???table_name??? 指定装入的表
BADFILE ???????????'c:\bad.txt'??? 可选,指定坏文件地址,缺省在当前目录下生成与原文件名一致的.bad文件
APPEND????????????原先的表有数据就加在后面?????????????????????????????????????????????? ※注一
FIELDS ??TERMINATED ???BY ???','???OPTIONALLY ???ENCLOSED ?BY '"'?????????? ※注二
TRAILING ????NULLCOLS???????????表的字段没有对应的值时允许为空
************* 下面是表的字段
(
col_1 ,
col_2 ,
col_filler ??FILLER ??????????????? // FILLER 关键字 ???此列的数值不会被装载
// 如: ?lg, lg, not 结果 lg lg
)?
BEGINDATA?????????????? 对应开始的 INFILE * 要导入的内容就在control文件里
10,Sql,what
20,lg,show
注一:
************* 以下是4种装入表的方式
APPEND??????????????? 原先的表有数据 就加在后面
INSERT????????????????? 装载空表 如果原先的表有数据 sqlloader会停止 默认值
REPLACE?????????????? 原先的表有数据 原先的数据会全部删除
TRUNCATE?????????? 指定的内容和replace的相同 会用truncate语句删除现存数据
注二:
// TERMINATED ???BY????WRITESPACE ????????????????????????????表示以空白分割
如果没声明FIELDS ???TERMINATED??BY ????',' 时,可以用下面两种方式实现同样功能:
1、为每一列指定分隔符
?(
?col_1[interger external] TERMINATED BY ',' ,
?col_2 [date "dd-mon-yyy"] TERMINATED BY ',' ,? ??????????? //插入DATE数据
?col_3 [char] TERMINATED BY ',' OPTIONALLY ENCLOSED BY 'lg'
?)
2、用位置告诉字段装载数据
?(
col_1position(1:2),
col_2 position(3:10),
col_3 position(*:16), ???????????????? // 这个字段的开始位置在前一字段的结束位置
col_4 position(1:16),
col_5 position(3:10) char(8)???? // 指定字段的类型
?)
示例二: 使用自定义的函数 ?????????????// 解决的时间问题
在控制文件可以写入日期,但无法插入时间,写一个函数来处理这方面的问题。该函数要在Oracle中执行。
create?? or? replace? function my_to_date( p_string in varchar2 ) return date
as
type? fmtArray? is? table? of? varchar2(25);
l_fmtsfmtArray? :=? fmtArray( 'dd-mon-yyyy', 'dd-month-yyyy', 'dd/mm/yyyy',
?'dd/mm/yyyyhh24:mi:ss' ); ??--要转换的格式,可在这里添加想要的格式。
l_return date; ??--返回的日期
begin
for i in 1 .. l_fmts.count? loop
begin
l_return :=to_date( p_string, l_fmts(i) ); ???--用上面定义的格式转化日期
exception
when