首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

C++ 呼叫 BCP 命令高效匯入文字檔至 SQL Server:從逐筆 INSERT 到批次匯入的效能躍升

     編輯:關於SqlServer

問題背景

伺服器運行產生大量 Log 檔案(40 萬筆+),需分析資料。嘗試以 C++ 讀取檔案逐筆 INSERT 入庫,耗時 1 小時以上,完全無法接受。

解決方案:BCP 批次匯入

BCP 簡介

  • SQL Server 內建大量複製工具(bcp.exe),支援文字檔、原生格式高速匯入/匯出。
  • 屬於命令列工具,可透過 xp_cmdshell 在 T-SQL 中呼叫,或直接在作業系統層執行。

T-SQL 呼叫語法


EXEC master..xp_cmdshell 
'bcp DatabaseName..TableName in "FilePath" -c -t"Delimiter" -S"ServerName" -U"UserName" -P"Password"';
參數說明
in匯入模式(out 為匯出)
-c字元模式(預設 tab 分隔、換行結束)
-t"Delimiter"指定欄位分隔符(如 -t"," 為 CSV)
-S目標伺服器名稱
-U / -P登入帳號密碼
-f format_file使用格式化檔案(複雜對應時)
-b batch_size批次大小(預設全部),建議 10000-50000
-h "TABLOCK"大量載入提示,鎖定整張表加速

C++ Builder 實作:寫 .bat 檔再 ShellExecute


// 1. 產生 .bat 內容(不含 xp_cmdshell,直接是 bcp 命令)
AnsiString batContent = 
  "bcp MyDB..MyTable in \"C:\\Data\\log.txt\" "
  "-c -t\",\" -S\"MyServer\" -U\"sa\" -P\"pwd\" -b 50000 -h \"TABLOCK\"";

// 2. 寫入暫存 .bat 檔
AnsiString batPath = "C:\\Temp\\import_log.bat";
std::ofstream ofs(batPath.c_str());
ofs << batContent.c_str();
ofs.close();

// 3. 執行 .bat(非同步或同步視需求)
HINSTANCE hResult = ShellExecute(
  NULL, "open", batPath.c_str(), NULL, NULL, SW_HIDE
);
if ((int)hResult <= 32) {
  // 執行失敗處理
}

效能對比

方式40 萬筆耗時備註
逐筆 INSERT (C++ 讀檔 + SQL)~ 1 小時+網路往返、解析編譯、記錄日誌逐筆
BCP 批次匯入~ 7 分鐘大量載入路徑、最小化記錄、鎖定優化
BULK INSERT (T-SQL)~ 5-6 分鐘在資料庫引擎內執行,無進程切換開銷

進階替代方案:BULK INSERT / SqlBulkCopy

  • T-SQL BULK INSERT:BULK INSERT TableName FROM 'FilePath' WITH (FIELDTERMINATOR=',', ROWTERMINATOR='\n', BATCHSIZE=50000, TABLOCK); — 純資料庫端執行,效能略優於 BCP。
  • ADO.NET SqlBulkCopy:C# 專用高效大量複製類別,WriteToServer(DataTable) 或 WriteToServer(IDataReader),物件導向、型別安全、支援 ColumnMappings。
  • 格式化檔案:複雜欄位對應、跳過欄位、資料轉換時使用 -f fmt.fmt。

實務注意事項

  1. 權限:執行帳號需有 bulkadmin 伺服器角色或 INSERT 權限 + ADMINISTER BULK OPERATIONS。
  2. 檔案存取:SQL Server 服務帳號需能讀取檔案路徑(共享資料夾需權限)。
  3. 錯誤處理:-e err.log 導出錯誤列,匯入後檢查錯誤日誌。
  4. 編碼:-c 使用 ANSI/MBCS;Unicode 檔案用 -w (寬字元)。
  5. 觸發器/約束:預設不觸發 Trigger、不檢查 CHECK/FK 約束,需加 -h "CHECK_CONSTRAINTS" 或 FIRE_TRIGGERS。

結論

大量文字檔匯入 SQL Server,**BCP/BULK INSERT/SqlBulkCopy** 是標準高效路徑,效能較逐筆 INSERT 提升 10-100 倍。C++ 應用可透過 ShellExecute 呼叫 .bat 包裝 BCP,或改用 ADO/OLE DB 直接呼叫 BULK INSERT,避免外部進程依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved