使用sqlldr匯入日期格式欄位的問題

regonly1發表於2009-04-17

有這麼一個資料,按照一分鐘統計資料的查詢數,欄位內容:
stat_date date, stat_num number(10)
stat_date表示統計日期,stat_num表示統計數目
資料如下:
2009-03-04 15:40:00, 4454
2009-03-04 15:41:00, 3360
2009-03-04 15:42:00, 7543
現要將這些資料匯入到資料庫的w_ldap_stat表中,我首先想到了用
awk將資料組裝成SQL語句。即每條記錄一個insert語句插入到資料庫
中。以前也做過類似的指令碼。但是感覺這樣比較繁瑣,而且也沒有必
要,因為Oracle已經為我們提供了一個現成的工具:sqlldr。
使用這個工具,我們就不用將每行記錄都組裝成insert語句來插入了。
使用sqlldr載入資料,首先需要建立一個控制檔案,用於對要匯入的數
據進行針對性的配置:
------------------------------ldapload.ctl----------------------------
load data
infile '20090417.dat' --指定要匯入的檔名
--insert                           --插入資料,要求源資料表為空
append                       --擴充套件資料,在原表基礎上增加資料
--replace                        --替換資料,刪除原有資料,再插入新資料
into table w_ldap_stat  --指定表名
fields terminated by ','   --指定欄位分隔符
(stat_date, stat_num)   --指定匯入對應的欄位

使用sqlldr進行匯入:
sqlldr control=ldapload.ctl
結果匯入情況如下:
Number to load: ALL
Number to skip: 0
Errors allowed: 50
Bind array:     64 rows, maximum of 256000 bytes
Continuation:    none specified
Path used:      Conventional

Table W_LDAP_STAT, loaded from every logical record.
Insert option in effect for this table: APPEND

   Column Name                  Position   Len  Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
STAT_DATE                           FIRST     *   ,  O(") CHARACTER
STAT_NUM                             NEXT     *   ,  O(") CHARACTER


Data File 30.dat -

Record 1: Rejected - Error on table W_LDAP_STAT, column STAT_NUM.
Column not found before end of logical record (use TRAILING NULLCOLS)
Record 2: Rejected - Error on table W_LDAP_STAT, column STAT_NUM.
Column not found before end of logical record (use TRAILING NULLCOLS)
Record 3: Rejected - Error on table W_LDAP_STAT, column STAT_NUM.
Column not found before end of logical record (use TRAILING NULLCOLS)
...
Record 7: Rejected - Error on table W_LDAP_STAT, column STAT_DATE.
ORA-01861: literal does not match format string

Record 8: Rejected - Error on table W_LDAP_STAT, column STAT_DATE.
ORA-01861: literal does not match format string
MAXIMUM ERROR COUNT EXCEEDED - Above statistics reflect partial run.
....
Table W_LDAP_STAT:
  0 Rows successfully loaded.
  51 Rows not loaded due to data errors.
  0 Rows not loaded because all WHEN clauses were failed.
  0 Rows not loaded because all fields were null.
從日誌中可以看到,出現了兩個錯誤。
一個是stat_num欄位有插入空資料的情況,這個的確是不需要的資料,可以排除。
一個是stat_date欄位出現了ORA-01861錯誤,日期格式不匹配。這個是為什麼呢?
難道是在源資料中還要轉成日期格式?如下:
to_date('2009-03-04 15:40:00','yyyy-mm-dd hh24:mi:ss'), 4454
to_date('2009-03-04 15:41:00','yyyy-mm-dd hh24:mi:ss'), 3360
to_date('2009-03-04 15:42:00','yyyy-mm-dd hh24:mi:ss'), 7543
再次匯入出現如下錯誤:
Record 1: Rejected - Error on table W_LDAP_STAT, column STAT_DATE.
ORA-01858: a non-numeric character was found where a numeric was expected

Record 2: Rejected - Error on table W_LDAP_STAT, column STAT_DATE.
ORA-01858: a non-numeric character was found where a numeric was expected

Record 3: Rejected - Error on table W_LDAP_STAT, column STAT_DATE.
ORA-01858: a non-numeric character was found where a numeric was expected
奇怪了,是什麼原因呢?難道是因為空格將日期和時間分開的緣故?
於是嘗試增加
optionally enclosed by '"' 
用以把對應的欄位給引起來,表示這是一個欄位的內容
"2009-03-04 15:40:00", 4454
"2009-03-04 15:41:00", 3360
"2009-03-04 15:42:00", 7543
但匯入還是失敗。難道是我比較笨,不能理解sqlldr的功能?
找找網上看,看有沒有跟我一樣笨的。結果不搜不知道一搜一大堆。
看來這個不是個別問題啊,是普遍存在的,老外也有不少遇到的。
最後看到一個解決方法,就是在控制檔案中,對匯入的日期的欄位進行格式化:
stat_date timestamp 'yyyy-mm-dd hh24:mi:ss'
即如下:
--------------------------------ldapload.ctl-------------------------------
load data
infile 'test.dat'
--infile '29.dat'
--insert
append
into table w_ldap_stat
fields terminated by ','
optionally enclosed by '"'
(stat_date timestamp "yyyy-mm-dd hh24:mi:ss", stat_num)

這樣匯入就完全正常了。

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

相關文章