使用 sqlldr 匯入含中文的 CSV 檔案,資料庫呈現 ???? 或亂碼;但直接用 SQL `INSERT` 卻正常。主因是 sqlldr 客戶端字元集轉換設定錯誤。
sqlldr 讀取資料檔 → 依客戶端 NLS_LANG 解碼 → 轉換為資料庫字元集 → 寫入。若 NLS_LANG 與資料檔實際編碼不符,解碼階段即產生錯誤字元,後續轉換無力回天。
# Linux/Unix (bash)
export NLS_LANG=TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950 # Big5 檔案
export NLS_LANG=TRADITIONAL CHINESE_TAIWAN.AL32UTF8 # UTF-8 檔案
# Windows CMD
set NLS_LANG=TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950
# Windows PowerShell
$env:NLS_LANG = "TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950"
執行 sqlldr 前務必在同一 Shell 設定。驗證方式:echo %NLS_LANG% 或 env | grep NLS_LANG。
LOAD DATA
CHARACTERSET ZHT16MSWIN950 -- 或 UTF8, AL32UTF8
INFILE 'data.csv'
INTO TABLE target_table
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
( col1, col2, col3 )
優先級高於環境變數,適合腳本自包含部署。
SELECT value FROM v$nls_parameters WHERE parameter = 'NLS_CHARACTERSET';
-- 常見結果:AL32UTF8 (推薦)、ZHT16MSWIN950、ZHT16HKSCS
原則:資料檔編碼 = NLS_LANG/CHARACTERSET 設定 = 資料庫字元集或可無損轉換。
sqlldr 版本與 Oracle Client 版本不一致,導致 NLS 解析差異。export NLS_LANG=...AL32UTF8 或 Control File 寫 CHARACTERSET AL32UTF8。