SqlBulkCopy提供了一種將數據復制到Sql Server數據庫表中高性能的方法。SqlBulkCopy 包含一個方法 WriteToServer,它用來從數據的源復制數據到數據的目的地。 WriteToServer方法可以處理的數據類型有DataRow[]數組,DataTable 和 DataReader。 你可以根據不同的情形使用不同的數據類型。SqlBulkCopy其原理是采用了SQL Server的BCP協議進行數據的批量復制。
用法
1、將數據庫中的表復制到另一個數據庫中的表。
本例將Pubs數據庫的stores表中的資料復制到Northwind數據庫的store表中。這兩個表結構相同。
using System.Data; using System.Data.SqlClient; using System.Configuration; /// <summary> /// 數據庫中的表復制到另一個數據庫中的表 /// </summary> private void SqlBulkCopyMethod() { try { SqlConnection connetionPub = new SqlConnection(ConfigurationManager.ConnectionStrings["PubsDB"].ConnectionString); using (connetionPub) { SqlCommand commandPub = connetionPub.CreateCommand(); using (commandPub) { commandPub.CommandText = "select * from stores"; commandPub.CommandType = System.Data.CommandType.Text; connetionPub.Open(); SqlConnection connectionBulkCopy = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindDB"].ConnectionString); using (connectionBulkCopy) { connectionBulkCopy.Open(); SqlDataReader dataReader = commandPub.ExecuteReader(); SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionBulkCopy); using (bulkCopy) { bulkCopy.DestinationTableName = "store"; bulkCopy.WriteToServer(dataReader); } } } } } catch (Exception ex) { throw ex; } }
2、將DataTable中的資料批量插入到數據庫中。
using System.Data; using System.Data.SqlClient; using System.Configuration; /// <summary> /// 將表中資料批量插入到數據庫 /// 轉自:http://www.cnblogs.com/mrliuc/archive/2011/01/18/1938271.html /// </summary> /// <param name="connectionString"></param> /// <param name="TableName"></param> /// <param name="dt"></param> private void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt) { using (SqlConnection conn = new SqlConnection(connectionString)) { using (SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction)) { try { sqlbulkcopy.DestinationTableName = TableName; for (int i = 0; i < dt.Columns.Count; i++) { sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); } sqlbulkcopy.WriteToServer(dt); } catch (System.Exception ex) { throw ex; } } } }
在博客園中看到下邊文章挺有用處,此處摘過來。原文:http://www.cnblogs.com/stalwart/archive/2011/01/07/1930207.html
1、從一個表 復制數據到另一個表
using System.Data; using System.Data.SqlClient; using System.Configuration; /// <summary> /// 從一個表復制到別一個表 /// </summary> private void PerformBulkCopy() { string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; // 源 using (SqlConnection sourceConnection = new SqlConnection(connectionString)) { SqlCommand myCommand = new SqlCommand("SELECT * FROM Products_Archive", sourceConnection); sourceConnection.Open(); SqlDataReader reader = myCommand.ExecuteReader(); // 目的 using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { // 打開連接 destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) { bulkCopy.BatchSize = 500; bulkCopy.NotifyAfter = 1000; bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); bulkCopy.DestinationTableName = "Products_Latest"; bulkCopy.WriteToServer(reader); } } reader.Close(); } } public void bulkCopy_SqlRowsCopied(object obj, SqlRowsCopiedEventArgs e) { //執行事件處理方法 }
首先,我使用DataReader來從數據庫的表中讀取數據。 Products_Latest是目的表,因為數據要從Products_Archive表復制到Products_Latest表。 bulkCopy對象提供了一個SqlRowCopied事件,在每次處理完NotifyAfter屬性指定的行數時發生。 本例中的意思就是每處理完1000行就觸發一次該事件,因為NotifyAfter被設置成了1000。
BatchSize屬性是非常重要的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行數,在每一批次結束時,就將該批次中的行發送到數據庫。 我將BatchSize設置成了500,其意思就是reader每讀出500行就將他們發送到數據庫從而執行批量復制的操作。 BatchSize的默認值是“1”,其意思就是把每一行作為一個批次發送到數據庫。設置不同的BatchSize在性能上將給你帶來不同的結果。 你應該根據你的需求進行測試,來決定BatchSize的大小。
/// <summary> /// 不同表之間復制數據 /// </summary> private static void PerformBulkCopyDifferentSchema() { string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; DataTable sourceData = new DataTable(); // 源 using (SqlConnection sourceConnection = new SqlConnection(connectionString)) { SqlCommand myCommand = new SqlCommand("SELECT TOP 5 * FROM Products_Archive", sourceConnection); sourceConnection.Open(); SqlDataReader reader = myCommand.ExecuteReader(); // 目的 using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { // 打開連接 destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) { bulkCopy.ColumnMappings.Add("ProductID", "ProductID"); bulkCopy.ColumnMappings.Add("ProductName", "Name"); bulkCopy.ColumnMappings.Add("QuantityPerUnit", "Quantity"); bulkCopy.DestinationTableName = "Products_TopSelling"; bulkCopy.WriteToServer(reader); } } reader.Close(); } }
<?xml version="1.0" encoding="utf-8" ?> <Products> <Product productID="1" productName="Chai" /> <Product productID="2" productName="Football" /> <Product productID="3" productName="Soap" /> <Product productID="4" productName="Green Tea" /> </Products>
/// <summary> /// 使用XML作為數據源 /// </summary> private static void PerformBulkCopyXMLDataSource() { string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; DataSet ds = new DataSet(); DataTable sourceData = new DataTable(); ds.ReadXml(@"C:Products.xml"); sourceData = ds.Tables[0]; // 目的 using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { // 打開連接 destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) { // 列映射 bulkCopy.ColumnMappings.Add("productID", "ProductID"); bulkCopy.ColumnMappings.Add("productName", "Name"); bulkCopy.DestinationTableName = "Products_TopSelling"; bulkCopy.WriteToServer(sourceData); } } }
首先把XML文件讀進DataTable,然后再使用SqlBulkCopy類的WriteToServer方法。 因為目的表示是Products_TopSelling,所以我們必須執行列映射。