文件入库ORACLE自动化脚本
背景
现提供有一批表结构和数据文件,需要入库到ORACLE,通过sqlldr方式入库。
简单流程
开发语言/工具
shell是个好东西, 虽然没有 C++、Python、Java、C# 等编程语言强大,但也支持了基本的编程元素,而且能在LINUX上快速的开发实现功能,其中的awk命令极其强大,对运维人员来说极其方便。
SQL*Loader(sqlldr)是Oracle数据库系统提供的一个高速批量数据加载工具,它可以在极短的时间内加载数量庞大的数据,可以直接被前端应用程序调用,并具有数据过滤等功能。
生成配置文件脚本:create_ctl.sh
tablename=$1
filepath=$2
echo tablename:$tablename filepath:$filepath
echo "load data" >${tablename}.ctl
ls ${filepath}|awk '{print "infile \x27'${filepath}'"$1"\x27"}' >>${tablename}.ctl
cat >>${tablename}.ctl <<EOF
append
PRESERVE BLANKS
into table ${tablename}
fields terminated by X'01'
optionally enclosed by '"'
trailing nullcols
(
EOF
sqlplus -S user/passwd@sid <<EOF
spool ${tablename}.columntype ;
desc ${tablename};
spool off;
exit
EOF
cat ${tablename}.columntype|egrep -v '(-|Name|^$)'|awk -F ' ' '{if($2=="DATE"){print $1 " Date \x27yyyy-mm-dd hh24:mi:ss\x27"} else {print $1}}'|awk 'NR==1{print $1 $2};NR>1{print ","$0}' >>${tablename}.ctl
echo ")" >>${tablename}.ctl
rm -f ${tablename}.columntype
du -sh ${filepath}
调用sqlldr脚本:load.sh
logpath="..."
ctlpath="..."
tablename=$1
sqlplus -S user/passwd@sid <<EOF
truncate table ${tablename};
exit
EOF
sqlldr user/passwd@sid errors=5000 control=${ctlpath}${tablename}.ctl log=${logpath}${tablename}.log bad=${logpath}${tablename}.bad direct=true rows=200000
运行示例:
sh create_ctl.sh tablename /data/tablename/
nohup ./load.sh tablename >./ztablename.log &
当加载数据比较大的表时,最好建nologging表
ALTER TABLE tablename nologging;
sqlldr 的用法
使用语法:
Usage: SQLLDR keyword=value [,keyword=value,...]
常用参数说明:
userid
Oracle 的 username/password@servicename
control
控制文件,可能包含表的数据
log
记录导入时的日志文件,默认为 控制文件(去除扩展名).log
bad
坏数据文件,默认为 控制文件(去除扩展名).bad
data
数据文件,一般在控制文件中指定。用参数控制文件中不指定数据文件更适于自动操作
errors
允许的错误记录数,可以用他来控制一条记录都不能错
rows
多少条记录提交一次,默认为 64
skip
跳过的行数,比如导出的数据文件前面几行是表头或其他描述
load
表示并不导入所有的数据,只导入跳过skip参数后的指定条数据
bindsize
表示每次提交记录缓冲区的大小,默认256k
direct
使用直通路径方式导入,不走buffer cache,通过direct path api发送数据到服务器端的加载引擎,加载引擎按照数据块的格式处理数据并直接写向数据文件,因此效率较高(默认FALSE)
parallel
并行导入 仅在直接路径加载时有效(默认FALSE)
skip_unusable_indexes
默认为false,如果是true,则加载完数据时,就算此表索引不可用,数据加载完不会改变此索引状态,oracle 数据库中也有此同名参数,但顺序是先看sqlldr,再数据库
skip_index_maintenance
是否跳过索引维护,默认false,直接路径加载有效,如果设置为true,因加载完数据不维护索引,因此索引会失效
readsize
缓冲区大小,默认值:1048576单位字节,最大不超过20m,该参数仅当从数据文件读取时有效
sqlldr控制文件参数说明
load data
CHARACTERSET 'UTF8' //指定使用的字符集为UTF-8
infile '/data/filename' //指定数据文件位置,多个文件用写多行
append into table test //追加导入数据的表
fields terminated by ',' //字段之间的分隔值为逗号
optionally enclosed by '"' //界定符号为""
TRAILING NULLCOLS //没有值的字段设置为空
(
COMPANY , //从数据文件中读入的列
STARTDATE Date "yyyy-mm-dd" , //设置日期格式
ENDDATE Date "yyyy-mm-dd hh24:mi:ss" , //设置日期格式
ID "test.NEXTVAL", //ID的取值为序列
IMPDATE "to_date('2020-04-08 11:30:36','yyyy-mm-dd hh24:mi:ss')", //插入固定日期格式的值
FLAG constant"open" //constant 指定插入默认值"open",而不是从指定的数据文件中读取记录
)