vlambda博客
学习文章列表

文件入库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",而不是从指定的数据文件中读取记录
)