🧾【完整教學】SQL Server 大量匯入常見錯誤 4866/7301 一次搞懂與修好(含範例與檢查清單)
摘要(給新手也看得懂)
把大量資料(CSV/TSV)匯進 SQL Server 時,最常遇到兩個錯誤:
-
訊息 4866:系統說「某一列的欄位太長」。多半不是資料真的太長,而是分隔符或換行符設定錯,導致整行被塞進第一欄;或是編碼/BOM讓第一個欄位吃到怪字元。
-
訊息 7301:系統說找不到
IID_IColumnsInfo。意思是你用OPENROWSET(BULK …)時,引擎拿不到欄位結構;改用BULK INSERT或提供解析設定就會好很多。
本篇用工程師的方式,教你從檔案偵錯 → 正確匯入 → 問題復原的完整流程。所有範例皆為示意,與真實專案無關。
錯誤 4866 與 7301 到底在說什麼?
-
4866:資料行太長
直覺以為是欄位長度不夠,但 7 成以上其實是分隔字元/換行符/編碼設定錯,導致整列被塞進第一欄。 -
7301:IID_IColumnsInfo
代表OPENROWSET(BULK…)想拿欄位結構卻拿不到。解法是改用 BULK INSERT、或在OPENROWSET明確指定格式(例如FORMAT='CSV')、或使用格式檔。
5 分鐘快速檢查清單(先做這個!)
-
檔案是 CSV 還是 TSV?分隔字元是逗號還是 Tab?
-
換行是 LF (0x0A) 還是 CRLF (0x0D0A)?
-
編碼是 UTF-8(有/無 BOM) 還是 UTF-16 LE?
-
第一列是否標題?要不要
FIRSTROW = 2? -
目標表欄位長度夠嗎?必要時先匯 staging 表 再轉型。
-
檔案路徑對 SQL 服務帳號是否可讀?(不是你的 Windows 帳號)
先「看」檔案:用 SQL 預覽前幾行(判斷分隔/換行/編碼)
這段只把整個檔案當成文字看,不牽涉欄位結構,所以不會踩 7301。
你會得到什麼?
-
看到實際分隔(
,或\t) -
看到換行(行尾是否多個空白或奇怪符號)
-
看第一個字是否出現怪字元(可能是 BOM)
最穩的匯入法:BULK INSERT(CSV/TSV)
SQL Server 2017+ 支援
FORMAT='CSV'。TSV 也可搭配
FIELDTERMINATOR 指定 Tab。
舊版 SQL Server 不支援
FORMAT='CSV'?改用傳統語法:
你的環境不吃 UTF-8?把檔案另存 UTF-16 LE(含 BOM),並使用:
用 staging 表避開欄位長度問題(4866 終結者)
先匯到寬欄位的暫存表,再清理轉進正式表,就不怕 4866 連環爆。
一定要 OPENROWSET?三種安全用法
-
只讀整檔(不需欄位介面):不會踩 7301
-
CSV 解析器:提供欄位抽象給引擎
-
格式檔(Format File):把每欄型別/長度寫清楚(XML 或非 XML 格式皆可)。
適合複雜檔案或要長期維護的匯入流程。
編碼與換行:UTF-8、UTF-16、LF/CRLF 一次分清
-
UTF-8:
CODEPAGE='65001'。若是舊版 SQL 或工具不穩,改用 UTF-16 LE + DATAFILETYPE='widechar'。 -
LF (0x0A):Linux/Mac 常見。
-
CRLF (0x0D0A):Windows 常見。
-
BOM:UTF-8 with BOM 會讓第一欄多出不可見的 BOM,導致 4866。可在匯入時用對的
CODEPAGE,或先把檔案另存「UTF-8(無 BOM)」。
路徑與權限:為什麼明明我看得到檔案,SQL 卻讀不到?
-
SQL Server 讀檔是用服務帳號的權限(例如
NT SERVICE\MSSQLSERVER或你自訂的帳號),不是你登入 SSMS 的個人帳號。 -
建議把匯入檔放在 SQL Server 主機本機磁碟(如
C:\Import),並授予該服務帳號「讀取」權限。 -
若用 網路分享路徑(UNC),服務帳號若不是網域帳號,通常會讀不到。
命令列備案:用 bcp 快速驗證設定
想用最少參數就測分隔/換行/編碼是否正確,bcp
很好用:
-
-t \t指定 Tab 分隔 -
-r \n或-r \r\n指定換行 -
-C 65001指定 UTF-8
常見地雷與對策總表
| 症狀 | 可能原因 | 對策 |
|---|---|---|
| 4866:第一欄超長 | 分隔/換行錯、UTF-8 BOM |
確認
FIELDTERMINATOR、ROWTERMINATOR、CODEPAGE;或先匯
staging
|
| 7301:IID_IColumnsInfo |
OPENROWSET 沒欄位結構
|
用 BULK INSERT、或
FORMAT='CSV'、或格式檔、或
SINGLE_CLOB
|
| 匯入亂碼 | 編碼不符 |
UTF-8:CODEPAGE=65001;UTF-16:DATAFILETYPE='widechar'
|
| 某些列失敗 | 特殊字元、引號、逗號 |
加
FIELDQUOTE='"';清洗資料或改用 staging
|
| 我看得到檔案但 SQL 看不到 | 服務帳號沒權限 | 把檔案放本機並授權 SQL 服務帳號讀取 |
| 標題被當資料 | 忘記跳過第一列 |
FIRSTROW = 2
|
FAQ
Q1:我的檔案是 CSV 不是 TSV,要改什麼?
A:把 FIELDTERMINATOR='\t' 改成
',',其他設定相同。
Q2:到底用 BULK INSERT 還是 OPENROWSET?
A:匯入正式表推薦
BULK INSERT(穩、直覺);預覽與快速分析用
OPENROWSET(SINGLE_CLOB)
最不會踩雷。
Q3:為什麼有時候 UTF-8 還是會出事?
A:BOM、舊版 SQL、或來源工具導出的奇怪控制字元都可能影響。遇到就把檔案另存
UTF-16 LE + widechar,或先清洗字元。
Q4:欄位偶爾會超長,怎麼辦?
A:先到 staging(nvarchar(4000)),再用 LEFT()/TRY_CONVERT()
轉型到正式表。
結語
匯入錯誤 4866 與 7301 看似可怕,但其實是格式偵測與解析方式沒對齊。只要按本文流程:先預覽 → 定義分隔/換行/編碼 → 優先用 BULK INSERT → 必要時 staging → 權限路徑對齊,大多數問題都能在 15 分鐘內搞定。
留言
張貼留言