中文 Big5/GBK 編碼下,部分生僻字第二位元組與欄位分隔符 (如 | = 0x7C) 相同,導致匯入時誤判欄位邊界、資料整列位移。
| 字元 | Big5 編碼 | 分隔符 | | 結果 |
|---|---|---|---|
| 弢 | 0x8F 7C | 0x7C | 第二位元組被誤判為分隔符 |
| 韡 | 0xED 7C | 0x7C | 同理位移 |
測試發現 BCP.exe 能正確識別雙位元組字元,不會誤判分隔符,而 BULK INSERT、OPENROWSET、SSIS 平面檔案來源均會受影響。
bcp DatabaseName.Schema.TableName IN "C:\Data\Import.txt" `
-b 1000 -c -t"|" -r"|\n" -S . -U sa -P password
參數說明:
-b 1000:批次大小 1000 列-c:字元模式 (預設 \t 分欄、\n 換列)-t"|":覆寫欄位結束符為 |-r"|\n":列結束符為 |\n (資料檔每列以 |\n 結尾)-S .:本機預設實例bcp DatabaseName.Schema.TableName IN "C:\Data\Import.txt" `
-b 1000 -f "C:\Format\Import.fmt" -S . -U sa -P password
bcp DatabaseName.Schema.TableName FORMAT NULL -f Import.fmt -S . -U sa -P password10.0
5
1 SQLCHAR 0 20 "|" 1 Col1 ""
2 SQLCHAR 0 50 "|" 2 Col2 ""
3 SQLCHAR 0 10 "|" 3 Col3 ""
4 SQLINT 0 4 "|" 4 Col4 ""
5 SQLCHAR 0 100 "|\n" 5 Col5 ""
欄位對應:順序號、儲存型別、前綴長度、資料長度、結束符、資料表欄位序號、欄位名、定序
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 命令列參數 | 簡單、無需額外檔案 | 檔案 > ~25MB 時仍會誤判生僻字 | 小檔、臨時匯入、測試 |
| 格式檔 (-f) | 無大小限制、效能最佳、可複用、支援複雜型別 | 需維護 .fmt 檔案 | 生產環境、大檔、定期 ETL、生僻字多 |
| 參數 | 說明 |
|---|---|
-f format_file | 指定格式檔完整路徑 (注意 -f 後有空格) |
-c | 字元模式:char 儲存、\t 分欄、\n 換列 (被 -t/-r 覆寫) |
-t field_term | 自訂欄位結束符 (預設 \t) |
-r row_term | 自訂列結束符 (預設 \n) |
-b batch_size | 批次大小,建議 1000-5000,減少記憶體/日誌壓力 |
-h "TABLOCK" | 大量載入提示:表鎖、最小記錄、順序插入 |
-E | 保留身分值 (IDENTITY) |
-k | 保留 NULL (不轉換為預設值) |
☐ 資料檔編碼 = BCP -c 預期編碼 (通常為 ANSI/系統預設碼頁)
☐ 格式檔中 SQLCHAR 長度 ≥ 實際最大位元組長度
☐ 結束符在資料中不出現 (或使用格式檔精確定長)
☐ 目標資料表定序支援資料檔字元集
☐ 測試載入前 100 列驗證無位移
生僻字位移是雙位元組編碼與單位元組分隔符衝突的經典問題。**BCP + 格式檔**是 MSSQL 原生、高效、穩健的標準解法。