首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

SQL Server 大量資料處理兩大方案:SqlBulkCopy 批次插入與 SqlDataAdapter 批次更新完整範例

     編輯:ASP.NET 基礎

方案選擇指引

  • 純大量插入:SqlBulkCopy (BCP) 效能最佳
  • 混合插入/更新/刪除:SqlDataAdapter + UpdateBatchSize 效能優異

方案一:SqlBulkCopy 大量插入(含交易控制)

public static void BulkCopy(string connString, string tableName, DataTable dt)
{
    using (SqlConnection conn = new SqlConnection(connString))
    {
        conn.Open();
        using (SqlTransaction transaction = conn.BeginTransaction())
        {
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction))
            {
                bulkCopy.BatchSize = 2000;           // 每批 2000 筆
                bulkCopy.BulkCopyTimeout = 300;      // 逾時秒數
                bulkCopy.DestinationTableName = tableName;
                
                try
                {
                    // 欄位對應:DataTable 欄位名 = 資料表欄位名
                    foreach (DataColumn col in dt.Columns)
                    {
                        bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
                    }
                    
                    bulkCopy.WriteToServer(dt);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
    }
}

關鍵參數說明

屬性說明建議值
BatchSize每批次筆數,減少記憶體壓力1000-5000
BulkCopyTimeout逾時秒數(預設 30 秒)300+
ColumnMappings來源與目標欄位對應,順序不同時必設逐一 Add
SqlBulkCopyOptions選項:CheckConstraints, FireTriggers, KeepIdentity 等視需求

方案二:SqlDataAdapter 批次更新(支援 Insert/Update/Delete)

public static void Update(string connString, DataTable table)
{
    using (SqlConnection conn = new SqlConnection(connString))
    {
        SqlCommand comm = conn.CreateCommand();
        comm.CommandTimeout = 300;
        comm.CommandType = CommandType.Text;
        
        using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
        {
            SqlCommandBuilder commandBuilder = new SqlCommandBuilder(adapter);
            commandBuilder.ConflictOption = ConflictOption.OverwriteChanges;
            
            try
            {
                conn.Open();
                adapter.UpdateBatchSize = 5000; // 批次更新筆數
                
                // 開始交易
                adapter.SelectCommand.Transaction = conn.BeginTransaction();
                
                // 若 DataTable 有自訂 SelectCommand SQL
                if (table.ExtendedProperties["SQL"] != null)
                {
                    adapter.SelectCommand.CommandText = table.ExtendedProperties["SQL"].ToString();
                }
                
                adapter.Update(table); // 執行批次更新
                
                // 提交交易
                adapter.SelectCommand.Transaction.Commit();
            }
            catch (Exception ex)
            {
                if (adapter.SelectCommand != null && adapter.SelectCommand.Transaction != null)
                {
                    adapter.SelectCommand.Transaction.Rollback();
                }
                throw;
            }
        }
    }
}

關鍵技術點

  1. UpdateBatchSize:啟用批次更新,減少往返次數(預設 1,逐筆執行)
  2. SqlCommandBuilder:自動產生 INSERT/UPDATE/DELETE 指令,需資料表有主鍵
  3. ConflictOption.OverwriteChanges:衝突時以資料庫最新值覆蓋
  4. 交易控制:透過 SelectCommand.Transaction 統一管理
  5. ExtendedProperties["SQL"]:可攜帶自訂查詢 SQL 供 CommandBuilder 參考

效能比較與適用場景

指標SqlBulkCopySqlDataAdapter 批次更新
操作類型僅 INSERTINSERT / UPDATE / DELETE
速度極快(最接近 BCP 工具)快(批次模式下接近 BulkCopy)
記憶體分批處理,可控需載入完整 DataTable
觸發器可選擇 FireTriggers逐批觸發
身分值保留可選擇 KeepIdentity依資料表設定
適用場景資料匯入、ETL、日誌大量寫入離線編輯回寫、同步化、混合操作

實務建議

  1. 大量插入優先用 SqlBulkCopy,搭配交易確保一致性
  2. 需更新/刪除時用 SqlDataAdapter,設定 UpdateBatchSize > 1
  3. 資料量極大(百萬級)考慮分批次呼叫、暫存表、資料分割
  4. 生產環境務必測試批次大小對效能與記憶體的影響
  5. 避免在單一交易處理過多資料導致鎖定升級或記錄檔暴增
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved