逐筆 `INSERT` 或小批次參數化雖安全,但百萬筆動輒數小時。`BCP` 命令列雖快但難整合自動化流程。BULK INSERT 是 T-SQL 原生、可編程、高效能的最佳平衡點:100 萬筆 < 20 秒 (視硬體/網路/索引而定)。
BULK INSERT [Schema].[TableName]
FROM 'E:\Data\Import.txt' -- 檔案路徑 (伺服器端本地或 UNC 路徑)
WITH (
DATAFILETYPE = 'char', -- 'char' | 'native' | 'widechar' | 'widenative'
FIELDTERMINATOR = ',', -- 欄位分隔符
ROWTERMINATOR = '\n', -- 列分隔符 (Windows: '\r\n', Linux: '\n')
FIRSTROW = 2, -- 跳過標題列
TABLOCK, -- 關鍵:取得表級鎖 (Sch-M),允許最小記錄,大幅提速
CHECK_CONSTRAINTS, -- 檢查 CHECK/FOREIGN KEY (預設關閉,開啟會降速)
FIRE_TRIGGERS, -- 觸發 INSERT TRIGGER (預設關閉)
MAXERRORS = 0, -- 容錯筆數 (0 即失敗即停)
ERRORFILE = 'E:\Data\Err.log' -- 錯誤行導出檔
);
| 缺點 | 影響 | 解決方案 |
|---|---|---|
| 獨佔表鎖 (TABLOCK) | 導入期間無法讀寫該表 | 維護窗口執行;或導入暫存表再 `SWITCH PARTITION` / `sp_rename` 切換 (元資料操作,毫秒級) |
| 產生大量交易記錄 | 記錄檔暴增、I/O 飆升、備份窗口延長 | 臨時切換至大量記錄恢復模式 (見下文);或分批次導入 (每批 10-50 萬) 間隔備份記錄 |
| 來源檔案格式嚴格 | 欄位數/型別/分隔符不符即報錯 | 使用格式化檔案; 預處理腳本 (PowerShell/Python) 清洗資料; `ERRORFILE` 捕獲異常行人工處理 |
完整恢復模式下 `BULK INSERT` 仍會完整記錄每筆資料 (除非滿足最小記錄條件:`TABLOCK` + 空表/新頁面 + 無觸發器/無 FK/無計算欄位)。最穩妥:導入前切 `BULK_LOGGED`,導入後切回 `FULL` 並立即備份記錄。
-- 1. 切換至大量記錄模式 (元資料操作,極快)
ALTER DATABASE [TargetDB] SET RECOVERY BULK_LOGGED;
GO
-- 2. 執行大量導入 (配合 TABLOCK 觸發最小記錄)
BULK INSERT [TargetDB].[dbo].[DetailTable]
FROM 'E:\Data\Import.txt'
WITH (
DATAFILETYPE = 'char',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
TABLOCK, -- 必須!鎖表換取最小記錄
FIRSTROW = 2
);
GO
-- 3. 立即切回完整模式
ALTER DATABASE [TargetDB] SET RECOVERY FULL;
GO
-- 4. 關鍵:立即進行一次記錄備份,接上新的記錄鏈,確保可還原性
BACKUP LOG [TargetDB] TO DISK = 'E:\Backup\TargetDB_Log_AfterBulk.trn';
GO
當來源檔欄位順序、數量、型別與目標表不一致,或含引號/逸出字元時,使用 XML 格式化檔 (`*.fmt`)。
-- 1. 產生範本格式化檔
BCP [TargetDB].[dbo].[DetailTable] FORMAT nul -c -t, -r\n -f Detail.fmt -T -S.
-- 2. 編輯 Detail.fmt (XML 格式),調整 SOURCE 欄位對應、長度、終止符、COLLATION 等
-- 3. 使用格式化檔導入
BULK INSERT [TargetDB].[dbo].[DetailTable]
FROM 'E:\Data\Import.txt'
WITH (FORMATFILE = 'E:\Data\Detail.fmt', TABLOCK);
| 方案 | 速度 | 可編程性 | 記錄量 | 適用場景 |
|---|---|---|---|---|
| BULK INSERT + BULK_LOGGED | 極快 (GB/分級) | 純 T-SQL,Agent Job/SP 皆可 | 最小 (僅頁面配置) | 定期大量載入、ETL 階段、資料倉儲建模 |
| BCP.exe | 極快 | 命令列,需 xp_cmdshell/外部排程 | 最小 | 跨平台、無 SQL 連線環境、極大檔案 (>10GB) |
| SSIS (Data Flow) | 快 (平行管線) | 視覺化套件,部署管理完善 | 可控 (快速載入選項) | 複雜 ETL 轉換、多源合併、錯誤流導向、CDC |
| Table-Valued Parameter (TVP) | 中 (應用層組裝) | .NET/Java 直傳集合 | 完整 | 應用層批次業務寫入 (萬筆內) |
| INSERT ... VALUES (批次 1000) | 慢 | 標準 SQL | 完整 | 即時業務、小批次、需觸發器/約束檢查 |