使用 Bulk Copy 將大量資料複製到資料庫

xusir發表於2013-06-26

如果一次要向資料庫伺服器提交多條記錄 , 通常會執行多次Insert命令 , 這樣就為要插入的每個記錄執行一次與資料庫伺服器的往返 , 這就給伺服器增加了壓力 , 效率也大大的降低了... 

.Net FrameWork 2.0 新增功能 Bulk Copy 可以很快將大量資料載入到資料庫中 , 現在利用這一新功能來實現上述功能. 

這裡從 MS Sql Server 2000 的 NorthWind 的 Orders 表載入資料到 DateTable 模擬要向資料庫伺服器提交的多條記錄集 . 用 Tempdb 庫來模擬目標資料庫伺服器 . 

先在 Tempdb 建一個表 temp_orders

 

USE TEMPDB 
  CREATE TABLE TEMP_ORDERS 
  ( 
  TEMP_ORDERID INT, 
  TEMP_CUSTOMERID NCHAR(5), 
  TEMP_ORDERDATE DATETIME, 
  TEMP_SHIPNAME NVARCHAR(40) 
  )

  

protected void Page_Load(object sender, EventArgs e) 
  { 
  #region 從NorthWind的Orders表獲取要插入的資料 
  DataTable dtNorthWindOrders = new DataTable(); 
  using ( SqlConnection northWindConnection = new SqlConnection( "Data Source=.;Initial Catalog=NorthWind;Integrated Security=True" ) ) 
  { 
  using ( SqlDataAdapter northWindAdapter = new SqlDataAdapter( "SELECT ORDERID,CUSTOMERID,ORDERDATE,SHIPNAME FROM ORDERS" , northWindConnection ) ) 
  { 
  northWindAdapter.Fill( dtNorthWindOrders ); 
  } 
  } 
  #endregion 
  using ( SqlConnection tempdbConnection = new SqlConnection( "Data Source=.;Initial Catalog=Tempdb;Integrated Security=True" ) ) 
  { 
  tempdbConnection.Open( ); 
  using ( SqlTransaction tran = tempdbConnection.BeginTransaction( ) ) 
  { 
  SqlBulkCopy bulkCopyOrders = new SqlBulkCopy( tempdbConnection , SqlBulkCopyOptions.Default , tran ); 
  bulkCopyOrders.DestinationTableName = "TEMP_ORDERS"; 
  //將資料來源表欄位和目標表的欄位做個對映 
  bulkCopyOrders.ColumnMappings.Add( "ORDERID" , "TEMP_ORDERID" ); 
  bulkCopyOrders.ColumnMappings.Add( "CUSTOMERID" , "TEMP_CUSTOMERID" ); 
  bulkCopyOrders.ColumnMappings.Add( "ORDERDATE" , "TEMP_ORDERDATE" ); 
  bulkCopyOrders.ColumnMappings.Add( "SHIPNAME" , "TEMP_SHIPNAME" ); 
  bulkCopyOrders.BulkCopyTimeout = 1000; 
  //每處理10行觸發一個事件向頁面上輸出一個訊息 
  bulkCopyOrders.SqlRowsCopied += new SqlRowsCopiedEventHandler( onRowsCopy ); 
  bulkCopyOrders.NotifyAfter = 10; 
  try 
  { 
  bulkCopyOrders.WriteToServer( dtNorthWindOrders ); 
  tran.Commit( ); 
  } 
  catch ( Exception ex ) 
  { 
  Response.Write( ex.ToString( ) ); 
  } 
  finally 
  { 
  dtNorthWindOrders = null; 
  } 
  } 
  } 
  } 
  private void onRowsCopy ( object Sender , SqlRowsCopiedEventArgs args ) 
  { 
  Response.Write("已複製:"+ args.RowsCopied.ToString( ) + " 
" );
}

通過SQL SERVER 事件探察器發現執行的SQL為:

  insert bulk TEMP_ORDERS ([TEMP_ORDERID] Int, [TEMP_CUSTOMERID] NChar(5) COLLATE Chinese_PRC_CI_AS, [TEMP_ORDERDATE] DateTime, [TEMP_SHIPNAME] NVarChar(40) COLLATE Chinese_PRC_CI_AS)

 通過執行程式可以看出這個速度是相當的快 , 使用這個方法的最大優點是 : 減少對資料庫的訪問次數 .

  WriteToServer不僅可以處理 DataTable 物件 , 還可以處理 DataReader , DataRow 物件陣列 .

相關文章