來源:Prize_VS.xls(姓名、身分證、地址、郵遞區號)
目標:表 方案名.Prize_VS
Excel → 「另存為」→ CSV (逗號分隔) (*.csv) → Prize_VS.csv
**注意**:若欄位含逗號/換行,Excel 會自動加雙引號包裹,SQL*Loader 預設可識別。
input.ctlLOAD DATA
INFILE 'Prize_VS.csv'
APPEND
INTO TABLE 方案名.Prize_VS
TRAILING NULLCOLS
(
NAME TERMINATED BY ",",
IDCARD TERMINATED BY ",",
ADDRESS TERMINATED BY ",",
POSTALCODE TERMINATED BY ","
)
關鍵子句說明:
APPEND:資料追加(預設)。INSERT 要求表為空,REPLACE/TRUNCATE 會清空表。TRAILING NULLCOLS:若行尾欄位缺失,視為 NULL(避免「欄位不足」報錯)。TERMINATED BY ",":CSV 標準分隔符。若為 TAB 用 TERMINATED BY X'09',固定寬度用 POSITION(1:10)。sqlldr 用戶名/密碼@服務名 CONTROL=input.ctl
產出檔案:
input.log:詳細執行日誌(讀取行數、提交行數、錯誤統計、**必看**)。Prize_VS.bad:拋錯行(資料型別不符、約束違反等),修正後可重跑。Prize_VS.dsc:若用 DISCARDFILE 子句,存放不符合 WHEN 條件的行。表 test(field_a, field_b, field_c),field_c 取 sequence_field_c.NEXTVAL。
LOAD DATA
INFILE 'C:\test.csv'
TRUNCATE
INTO TABLE test
FIELDS TERMINATED BY ','
(
field_a,
field_b,
field_c "sequence_field_c.NEXTVAL"
)
原理:雙引號內為 **SQL 運算式**,每行載入時執行一次。同理可用 SYSDATE、UPPER(:field_a) 等任意合法 SQL 運算式。
| 參數 | 用途 | 範例 |
|---|---|---|
DIRECT=TRUE | 直接路徑載入,繞過 SQL 層,**極速**,但限制多(無觸發器、無外鍵、獨佔鎖) | sqlldr ... DIRECT=TRUE |
PARALLEL=TRUE | 並行直接載入,配合多控制檔/多檔案,需表分區 | sqlldr ... PARALLEL=TRUE |
ERRORS=999999 | 允許錯誤行上限(預設 50),防止少量髒資料中斷整批 | sqlldr ... ERRORS=10000 |
SKIP=1 | 跳過 CSV 首行標題 | sqlldr ... SKIP=1 |
BINDSIZE=2097152 | 綁定陣列大小(位元組),直接路徑下調大提升吞吐 | sqlldr ... BINDSIZE=8388608 |
READSIZE=2097152 | 讀取緩衝區大小 | sqlldr ... READSIZE=8388608 |
| 錯誤現象 | 原因 | 對策 |
|---|---|---|
| ORA-01722: invalid number | 數值欄位含非數字字符(如千分位逗號) | CSV 預處理移除,或控制檔用 TO_NUMBER(REPLACE(:col,',')) |
| ORA-01400: cannot insert NULL | NOT NULL 欄位缺值 | 檢查 CSV、或給預設值 DEFAULT 'N/A' |
| ORA-00001: unique constraint violated | 主鍵/唯一鍵重複 | 源資料去重、或用 WHEN 子句過濾 |
| 載入極慢 | 未用 DIRECT、索引/觸發器開啟、BINDSIZE 太小 | 按調優清單逐項落地 |