SqlBulkCopy(批量複製)使用方法

地址:http://www.cnblogs.com/scottckt/archive/2011/02/16/1955862.html


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的大小。

 

  2、在不同的映射表之間複製數據
       上面的例子中兩個表具有相同的結構。 有時,你需要在具有不同結構的表之間複製數據。
/// <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();
            }
        }
ColumnMappings集合用於映射源表和目的表之間的列。

  3、從XML文件複製數據到數據庫的表中
    數據源並不侷限於數據庫的表,你也可以使用XML文件做數據源。 這裏有一個非常簡單的使用XML文件做數據源進行批量複製操作的例子。

<?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,所以我們必須執行列映射。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章