採用sqlldr定時將文字檔案載入進入資料庫

myownstars發表於2011-02-25
需求:每個小時前臺生成一個追蹤檔案,檔名格式為yyyymmddhh,存放在linux伺服器上,要求每小時將上一個小時生成的檔案匯入資料庫
解決方案:
採用sqlldr可以快速的將外部文字檔案載入到資料庫中,根據要求建立控制檔案和shell指令碼,其中控制檔案如下
[root@justin justin]# more control.ctl
load data
characterset UTF8
infile '/justin/source_file.csv'
append into table abc
fields terminated by ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
"ID" sequence(MAX,1),
"desc" char(4000),
"TIME" DATE "YYYY-MM-DD HH24:MI:SS"
)
由於要採用直接路徑載入,所以必須在控制檔案中就定義好字符集(需要同資料庫保持一致),否則sqlldr會採用OS的字符集載入,中文出現亂碼;
文字檔案中沒有主鍵ID,需要在載入的時候就要為其生成,所以採用sequence(MAX,1)函式

#!/bin/bash

ORACLE_HOME=/data/oracle/product/10205/db1
export ORACLE_HOME


folder=/justin/--檔案儲存路徑

#get the past time value
date1=`date --date='1 hour ago'  +%Y%m%d%H`
date2=`date --date='15 day ago'  +%Y%m%d%H`

#rename the file generated one hour ago to source_file.csv, which would be called by control.ctl
mv "$folder""$date1"  "$folder"source_file.csv--因為每次載入的檔名稱都不一樣,所以需要其重新命名成一個固定的檔案,名字需要跟control.ctl中的保持一致
#call sqlldr, with control as control.ctl
$ORACLE_HOME/bin/./sqlldr userid=justin/***** control="$folder"control.ctl  readsize=500000 rows=2000  direct=true log="$folder""$date1"-51
#rename bad file if generated
if [ -f "$folder"source_file.bad ]; then
mv "$folder"source_file.bad "$folder""$date1"-51.bad
fi

#roll back the rename operation
mv "$folder"source_file.csv "$folder""$date1"

#if the file generated by 15 days ago still exist, then drop them
if [ -f "$folder""$date2" ]; then--刪除過期檔案
  rm "$folder""$date2"
fi
if [ -f "$folder""$date2"-51.log ]; then
  rm "$folder""$date2"-51.log
fi
if [ -f "$folder""$date2"-51.bad ]; then
  rm "$folder""$date2"-51.bad
fi

最後將這個shell指令碼加入至crontab設定每小時執行一次即可

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-688368/,如需轉載,請註明出處,否則將追究法律責任。

相關文章