1. 程式人生 > >Oracle sqlldr使用的幾個注意事項

Oracle sqlldr使用的幾個注意事項

 Oracle sqlldr是將大量資料批量匯入Oracle資料表的工具,直接可以在命令符下執行。

    最近同事在使用sqlldr的時候,碰到一些問題同時也做了些研究,現借題整理如下:

    1. “SQL*Loader-566”錯誤 

SQL*Loader: Release 10.2.0.1.0 - Production on 星期四 5 5 21:53:27 2011

Copyright (c) 1982, 2005, Oracle. All rights reserved.

達到提交點 - 邏輯記錄計數 1
SQL*Loader-501:
無法讀取檔案 (data_cn_01.dat)
SQL*Loader-566:

在資料檔案的結尾處找到部分記錄
SQL*Loader-2026:
載入因 SQL載入程式無法繼續而被終止。資料處理完成, 按任意鍵結束

    經過跟蹤測試,發現是資料檔案的問題。問題出在最後一行資料分隔符號後面沒有回車,特別注意下面資料檔案####後面還有一行空行。  

CN200780027488.5||||CN101490018||||本發明涉及新的遊離鹼形式或酸加成鹽形式的式(I)的大環化合物
####
 

    2. “資料檔案的欄位超出最大長度”錯誤

    這個問題網上很容易找到答案,sqlldr對於字元型別預設長度為255,如果超過255需要指定長度,見紅色下面ctl檔案中的紅色字型:

LOAD DATA 
 
INFILE 'data_cn_01.dat' "STR X'0D0A232323230D0A'"
INTO TABLE tpis_pat_cn
APPEND
FIELDS TERMINATED BY '||||'
TRAILING NULLCOLS
(
 
an,
 
pn,
 
abCHAR(4000),
 
source CONSTANT 'SIPO',
 
patent_id "seq_tpis_pat_base.NEXTVAL"

    3. “ORA-12899: 列的值太大”錯誤 

記錄 1: 被拒絕 - TPIS_PAT_CN的列 AB 出現錯誤。
ORA-12899:

"PIS"."TPIS_PAT_CN"."AB"的值太大 (實際值: 2800,最大值: 2000)

    這個錯誤很明顯,和INSERT等DML語句提示錯誤一致。其錯誤原因在於從文字中讀取的欄位值超過了資料庫表字段的長度,需要用Oracle函式解決: 

LOAD DATA  
 
...

TRAILING NULLCOLS
(
  ...

abCHAR(4000) "SUBSTRB(:ab,1,2000)",
 
...

    4. “資料檔案的欄位超出最大長度”錯誤 

情況一:

記錄 1: 被拒絕 - TPIS_PAT_CN的列 AB 出現錯誤。資料檔案的欄位超出最大長度

情況二:

記錄 1: 被拒絕 - TPIS_PAT_CN出現錯誤。
ORA-01461:
僅能繫結要插入 LONG列的 LONG

    以上第一種錯誤情況是由於資料檔案中的欄位值真實長度超過指定的4000長度,所以提示“資料檔案的欄位超出最大長度”錯誤。可能有人準備將“CHAR(4000)”改為“CHAR(8000)”,這時就會出現第二種錯誤。其原因在於:字元型別在PL-SQL中做為變數存大,最大可支援32767個位元組,但在SQL中通常只能夠支援到4000位元組(NCHAR為2000),因此如果宣告的變數長度超出了SQL中型別長度,並且變數實際值也超出型別可接受最大值時,就會觸發ORA-01461錯誤。

    所以當資料檔案中的欄位值真實長度超過4000長度時,只有一個方法:將資料表字段型別改為CLOB型別或者新增加一個臨時CLOB欄位,sqlldr中的“CHAR(32767)”對於CLOB欄位有效。匯入後再通過SQL語句更新到真實欄位中。

LOAD DATA  
 
...

TRAILING NULLCOLS
(
  ...

ab_bkCHAR(32767),
 
...

-- ab_bk更新到ab中的SQL語句

UPDATE TPIS_PAT_CN SET ab=SUBSTR(ab_bk,1,1000) WHERE ab_bk IS NOT NULL AND patent_id>=337462

    很遺憾,查閱了大量國外資料,sqlldr沒有更好的方法處理值超過4000長度的非CLOB欄位匯入工作。所以只能有以下兩種選擇:

    方案一:當然在匯入之前通過程式進行預處理,但這也不是件簡單的事。

    方案二:忽略此欄位的內容。通過在控制檔案中指定“ac FILLER CHAR(32767)”即可實現忽略此欄位的內容。

 參考資料:

     1. ORA-01461的解決過程

     2. SQL Loader- Field in data file exceeds maximum length