命令語法
sqlldr userid=user/pass control=emp.ctl data=emp.dat bad=emp.bad log=emp.log
常用參數:USERID、CONTROL、DATA、BAD、LOG、DISCARD、ERRORS(允許錯誤筆數)、ROWS(陣列大小)、BINDSIZE、SILENT、DIRECT=TRUE(直徑載入)。
控制檔三段式結構
-- 1. 全域選項
LOAD DATA
INFILE 'emp.dat' -- 或 INFILE * 配合 BEGINDATA
APPEND -- INSERT/REPLACE/TRUNCATE
INTO TABLE emp
FIELDS TERMINATED BY '|' -- 分隔符
(
-- 3. 欄位映射與資料型別
empno POSITION(1:4) INTEGER EXTERNAL,
ename CHAR(20),
hiredate DATE 'YYYYMMDD',
sal DECIMAL EXTERNAL,
comm FLOAT EXTERNAL
)
-- 2. 內嵌資料(僅 INFILE * 時)
BEGINDATA
7369|SMITH|19801217|800|0
7499|ALLEN|19810220|1600|300
關鍵選項詳解
| 選項 | 說明 | 範例 |
FIELDS TERMINATED BY | 分隔符,支援 WHITESPACE、十六進位 X'09' (Tab) | FIELDS TERMINATED BY ',' |
POSITION(start:end) | 固定寬度欄位位置 | POSITION(1:10) |
FILLER | 跳過該欄位不載入 | col1 FILLER CHAR(10) |
RECNUM | 自動產生行號 | seq_no RECNUM |
SKIP n | 跳過前 n 行(如標題列) | SKIP 1 |
DATE 'fmt' | 日期格式轉換 | hiredate DATE 'DD-MON-YYYY' |
NULLIF col=BLANKS | 空白視為 NULL | comm NULLIF comm=BLANKS |
載入模式對比
| 模式 | 行為 | 前提 | 效能 |
| INSERT | 表必須為空,否則報錯 | 空表 | 基準 |
| APPEND | 追加資料,保留既有 | 無 | 快 |
| REPLACE | DELETE 全表再載入 | 需 DELETE 權限 | 中 |
| TRUNCATE | TRUNCATE 全表再載入 | 需 DROP ANY TABLE | 最快(無 UNDO) |
效能優化清單
- Direct Path Load:
sqlldr ... DIRECT=TRUE 繞過 SQL 層,直接格式化資料塊寫入,速度提升 5-10 倍。限制:需獨佔表、禁用觸發器/約束(稍後 ENABLE)、不支援 Cluster/Object 表。
- 大幅增加 ROWS/BINDSIZE:
ROWS=10000 BINDSIZE=20971520(20MB)減少網路往返。
- 並行載入:多個 SQL*Loader 會話載入同一表不同分區(
PARTITION 子句),需表分區、禁用索引/約束、載入後 REBUILD。
- 預先排序資料:按索引鍵排序輸入檔,減少索引維護開銷。
- UNRECOVERABLE/NOLOGGING:控制檔加
UNRECOVERABLE 或表設 NOLOGGING,最小化重做日誌(載入後必須備份)。
常見錯誤排查
ORA-01722 invalid number → 檢查數值欄位格式、千分位符號、科學記號。
ORA-01841 date format mismatch → 核對控制檔 DATE 格式與資料實際格式(含時區)。
SQL*Loader-500 → 檔案不存在或權限不足。
- BAD 檔大量記錄 → 檢查分隔符、引號嵌套、換行符(Windows CRLF vs Unix LF)。