使用SqlBulkCopy進行數據大批量的遷移

在ASP.NET 2.0中提供了一個新的類 SqlBulkCopy類,它在性能上的優點更超過了上面的方法,它能夠經過讓DataSet或是DataReader中大量的數據經過數據流直接進行裝載,而後能夠將這些記錄添加到指定的數據表中。
   SqlBulkCopy類只有在SQL Server的表中寫入數據,但在使用其它的數據庫時,能夠經過數據源來使用, SqlBulkCopy類主要包括一個實例方法WriteToServer,它用來把數據從一個數據源傳輸到另一個數據源。WriteToServer的方法能夠快速的寫入DataRow數組數據,DataTable和DataReader。在實際開發的過程當中,能夠視狀況而定,選擇咱們所喜歡的方法,咱們看它使用的方法:
  WriteToServer(DataTable)寫入數據表
  WriteToServer(DataRow)批次寫入數據行
  WriteToServer(DataTable,DataRowState)按行狀態寫入數據庫表
  WriteToServer(DataReader)寫入DataReader對象
  在多數狀況下,咱們選擇最好的方法是DataReader對象,由於DataReader是一個讀取只向前和只讀流的方式,因此它要比DataTable和DataRows更快,咱們如今來看看下面的代碼,它用來把數據從一張表中傳輸到另外一張表中。
  代碼清單:
   string strConnection = ConfigurationManager.AppSettings["conStr"].ToString();//讀取Web.config文件中的數據庫鏈接字符串
  SqlConnection sourceconnection = new SqlConnection(strConnection);//數據的鏈接方式是SQL Server
  sourceconnection.Open();//打開數據庫鏈接
  SqlCommand cmd = new SqlCommand("Select * from MSreplication_options");//經過命令來讀取SQL語句
  cmd.Connection = sourceconnection;//獲取鏈接方式
  SqlDataReader reader = cmd.ExecuteReader();//開始執和結果集,獲取DataReader記錄集
  //鏈接目標數據庫鏈接,而且打開數據庫鏈接方式,在此因爲調用同一個數據庫,鏈接字符串沒有變
  SqlConnection destinationConnection = new SqlConnection(strConnection);
  destinationConnection.Open();
  //調用SqlBulkCopy類的方法
  SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection);
  //獲取目標表的名稱
  bulkCopy.DestinationTableName = "destination";
  //寫入DataReader對象
  bulkCopy.WriteToServer(reader);
  //關閉各個對象
  reader.Close();
  sourceconnection.Close();
  destinationConnection.Close();
  上例中,咱們使用的是SQL Server 2005的master數據庫,咱們在使用 SqlBulkCopy的時候,須要瞭解一下它的幾個重要的屬性:
  BatchSize:屬性的整數值;或者若是未設置任何值,則爲零。每一批次中的行數。在每一批次結束時,將該批次中的行發送到服務器。
  BulkCopyTimeOu:超時以前操做完成所容許的秒數。若是操做超時,事務便不會提交,並且全部已複製的行都會從目標表中移除。
  ColumnMappings:返回 SqlBulkCopyColumnMapping 項的集合。列映射定義數據源中的列和目標表中的列之間的關係。若是數據源和目標表具備相同的列數,而且數據源中每一個源列的序號位置匹配相應目標列的序號位置,則無需 ColumnMappings 集合。可是若是列計數不一樣,或序號位置不一致,則必須使用 ColumnMappings,以確保將數據複製到正確的列中。
  DestinationTableName:指定的目標表中。
  NotifyAfter:屬性的整數值,或者若是未設置該屬性,則爲零。定義在生成通知事件以前要處理的行數。
  在ColumnMappings屬性中,咱們能夠看到 SqlBulkCopyColumnMapping 項,它主要是用來定義 SqlBulkCopy實例的數據源中的列與該實例的目標表中的列之間的映射。
  結合着上面 SqlBulkCopy的屬性咱們再來看一個綜合的例子,此例中咱們使用DataTable:
  在本例中,我先本身創建一個數據庫 SqlBulkCopySample,而後創建一個表TblOrder,它主要是用來把Northwind數據庫中的Orders表數據全導進來,因此它的表結構基本上和Orders同樣,它們以應的關係以下:
   ID (OrderID): int
  Name (ShipName): nvarchar(40)
  Address (ShipAddress): nvarchar(60)
  City (ShipCity): nvarchar(15)
  而後在Northwind數據中建立一個存儲過程,以下:
  CREATE PROCEDURE dbo.SelectOrders
  AS
  SELECT OrderID, ShipName, ShipAddress, ShipCity
  FROM Orders
  咱們在頁面中增長一個按鈕的點擊事件,當事件觸發的時候,執行的代碼以下:    private void btnStart_Click(object sender, EventArgs e)
  {
  String sourceConnectionString =
  "Data Source=127.0.0.1;Initial Catalog=Northwind;Integrated Security=True";
  String destinationConnectionString =
  "Data Source=127.0.0.1;;Initial Catalog=SqlBulkCopySample;Integrated Security=True";
  DataTable data = SelectDataFromSource(sourceConnectionString);//獲取數據
  CopyDataToDestination(destinationConnectionString, data);//複製數據
  }
  獲取數據很是簡單,它只是經過執行存儲過程返回一個DataTable的查詢結果集,以下:
   private DataTable SelectDataFromSource(String connectionString)
  {
  DataTable data = new DataTable();
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
  SqlCommand command = new SqlCommand("SelectOrders", connection);
  command.CommandType = CommandType.StoredProcedure;
  connection.Open();
  SqlDataReader reader = command.ExecuteReader();
  data.Load(reader);
  }
  return data;
  }
  接着,就執行數據複製的操做,此部分的代碼爲核心的部分,首先咱們經過建立四個 SqlBulkCopyColumnMapping對象,而後把兩個數據庫中的表之間的一一對應關係表述出來,而後設置好BatchSize及BulkCopyTimeout屬性,而後返回 SqlBulkCopyColumnMapping 項的集合,接着定義好目標表的名稱,以SqlRowsCopied事件處理程序,在定義在生成通知事件以前要處理的行數時,而後調用WriteToServer(DataTable) 方法寫入數據表,結束數據的複製,以下:      private void CopyDataToDestination(String connectionString, DataTable table)
  {
  SqlBulkCopyColumnMapping mapping1 =
  new SqlBulkCopyColumnMapping("OrderID", "ID");
  SqlBulkCopyColumnMapping mapping2 =
  new SqlBulkCopyColumnMapping("ShipName", "Name");
  SqlBulkCopyColumnMapping mapping3 =
  new SqlBulkCopyColumnMapping("ShipAddress", "Address");
  SqlBulkCopyColumnMapping mapping4 =
  new SqlBulkCopyColumnMapping("ShipCity", "City");
  SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString);
  bulkCopy.BatchSize = 100;
  bulkCopy.BulkCopyTimeout = 5;
  bulkCopy.ColumnMappings.Add(mapping1);
  bulkCopy.ColumnMappings.Add(mapping2);
  bulkCopy.ColumnMappings.Add(mapping3);
  bulkCopy.ColumnMappings.Add(mapping4);
  bulkCopy.DestinationTableName = "tblOrder";
  bulkCopy.SqlRowsCopied +=
  new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
  bulkCopy.NotifyAfter = 200;
  bulkCopy.WriteToServer(table);
  }
  在bulkCopy_SqlRowsCopied的處理中,我只簡單的經過展示給用戶一個友好的提示信息讓你能夠知道目前有多少行被複製成功。代碼以下:      private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
  {
  MessageBox.Show
  (String.Format("{0} Rows have been copied.", e.RowsCopied.ToString()));
  }
  這樣,在平時的開發中,咱們能夠靈活的在ASP.NET中使用 SqlBulkCopy幫助咱們複製大量的數據之間的數據源和數據表,並改善應用程序的性能。
  獲取數據很是簡單,它只是經過執行存儲過程返回一個DataTable的查詢結果集,以下:
   private DataTable SelectDataFromSource(String connectionString)
  {
  DataTable data = new DataTable();
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
  SqlCommand command = new SqlCommand("SelectOrders", connection);
  command.CommandType = CommandType.StoredProcedure;
  connection.Open();
  SqlDataReader reader = command.ExecuteReader();
  data.Load(reader);
  }
  return data;
  }
  接着,就執行數據複製的操做,此部分的代碼爲核心的部分,首先咱們經過建立四個 SqlBulkCopyColumnMapping對象,而後把兩個數據庫中的表之間的一一對應關係表述出來,而後設置好BatchSize及BulkCopyTimeout屬性,而後返回 SqlBulkCopyColumnMapping 項的集合,接着定義好目標表的名稱,以SqlRowsCopied事件處理程序,在定義在生成通知事件以前要處理的行數時,而後調用WriteToServer(DataTable) 方法寫入數據表,結束數據的複製,以下:      private void CopyDataToDestination(String connectionString, DataTable table)
  {
  SqlBulkCopyColumnMapping mapping1 =
  new SqlBulkCopyColumnMapping("OrderID", "ID");
  SqlBulkCopyColumnMapping mapping2 =
  new SqlBulkCopyColumnMapping("ShipName", "Name");
  SqlBulkCopyColumnMapping mapping3 =
  new SqlBulkCopyColumnMapping("ShipAddress", "Address");
  SqlBulkCopyColumnMapping mapping4 =
  new SqlBulkCopyColumnMapping("ShipCity", "City");
  SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString);
  bulkCopy.BatchSize = 100;
  bulkCopy.BulkCopyTimeout = 5;
  bulkCopy.ColumnMappings.Add(mapping1);
  bulkCopy.ColumnMappings.Add(mapping2);
  bulkCopy.ColumnMappings.Add(mapping3);
  bulkCopy.ColumnMappings.Add(mapping4);
  bulkCopy.DestinationTableName = "tblOrder";
  bulkCopy.SqlRowsCopied +=
  new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
  bulkCopy.NotifyAfter = 200;
  bulkCopy.WriteToServer(table);
  }
  在bulkCopy_SqlRowsCopied的處理中,我只簡單的經過展示給用戶一個友好的提示信息讓你能夠知道目前有多少行被複製成功。代碼以下:      private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
  {
  MessageBox.Show
  (String.Format("{0} Rows have been copied.", e.RowsCopied.ToString()));
  }
  這樣,在平時的開發中,咱們能夠靈活的在ASP.NET中使用 SqlBulkCopy幫助咱們複製大量的數據之間的數據源和數據表,並改善應用程序的性能。
相關文章
相關標籤/搜索