C# 使用SqlBulkCopy類批量復制大數據


特別注意  sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);

插入的時候列的順序可以不一致,但名稱和數據類型最好要保存一致。不一致時候,也能進行正確的轉換,除了比如DataTime數據類型,不能插入一個無效的string時間字符串。

本文轉載:http://zhoufoxcn.blog.51cto.com/792419/166052

參考http://www.cnblogs.com/scottckt/archive/2011/02/16/1955862.html

幾種數據庫的大數據批量插入

http://www.cnblogs.com/netuml/p/3719298.html

 

這篇文章不錯通過xml配置映射關系:http://www.cnblogs.com/pengyq/archive/2009/12/04/1616997.html

 用途說明:

前些日子,公司要求做一個數據導入程序,要求將Excel數據,大批量的導入到數據庫中,盡量少的訪問數據庫,高性能的對數據庫進行存儲。於是在網上進行查找,發現了一個比較好的解決方案,就是采用SqlBulkCopy來處理存儲數據。SqlBulkCopy存儲大批量的數據非常的高效,就像這個方法的名字一樣,可以將內存中的數據表直接的一次性的存儲到數據庫中,而不需要一次一次的向數據庫Insert數據。初次實驗,百萬級別的數據表,也只需幾秒時間內就可以完全的存入數據庫中,其速度,比傳統的Insert方法不止快很多倍

 


       MSDN摘要:Microsoft SQL Server 提供一個稱為 bcp 的流行的命令提示符實用工具,用於將數據從一個表移動到另一個表(表既可以在同一個服務器上,也可以在不同服務器上)。SqlBulkCopy 類允許編寫提供類似功能的托管代碼解決方案。還有其他將數據加載到 SQL Server 表的方法(例如 INSERT 語句),但相比之下 SqlBulkCopy 提供明顯的性能優勢。

使用 SqlBulkCopy 類只能向 SQL Server 表寫入數據。但是,數據源不限於 SQL Server;可以使用任何數據源,只要數據可加載到 DataTable 實例或可使用 IDataReader 實例讀取數據。

 

   ///   <summary>
        
///  
        
///   </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;
                    }
                }
            }
        }

 

 

 SqlBulkCopy使用使用用於自定義表類型作為存儲過程參數,批量寫入數據。
 
  如果,大家使用SQL Server  2008,它提供一個新的功能表變量(Table Parameters)可以將整個表數據匯集成一個參數傳遞給存儲過程或SQL語句。它的注意性能開銷是將數據匯集成參數(O(數據量))。
 
  現在,我們修改之前的代碼,在SQL Server中定義我們的表變量,具體定義如下:
 -- =============================================
-- Author:        JKhuang
-- Create date:  08/ 16/ 2012
-- Description:    Declares a user table paramter.
-- =============================================
CREATE TYPE jk_users_bulk_insert AS TABLE (
    user_login varchar( 60),
    user_pass varchar( 64),
    user_nicename varchar( 50),
    user_email varchar( 100),
    user_url varchar( 100),
    user_activation_key varchar( 60),
    user_status  int,
    display_name varchar( 250)
)
 
  上面,我們定義了一個表參數jk_users_bulk_insert,接着我們定義一個存儲過程接受表參數jk_users_bulk_insert,具體定義如下:
 -- =============================================
-- Author:        JKhuang
-- Create date:  08/ 16/ 2012
-- Description:    Creates a stored procedure, receive
-- a jk_users_bulk_insert argument.
-- =============================================
CREATE PROCEDURE sp_insert_jk_users 
@usersTable jk_users_bulk_insert READONLY 
AS
INSERT INTO jk_users (user_login, user_pass, user_nicename, user_email, user_url, 
user_activation_key, user_status, display_name, user_registered) 
SELECT user_login, user_pass, user_nicename, user_email, user_url, 
user_activation_key, user_status, display_name, GETDATE() 
FROM @usersTable 
  接下我們在客戶端代碼中,調用存儲過程並且將表作為參數方式傳遞給存儲過程。
  var sw = Stopwatch.StartNew();
using ( var conn =  new SqlConnection(ConfigurationManager.ConnectionStrings[ " SQLCONN2 "].ToString()))
{
    conn.Open();
     /// / Invokes the stored procedure.
     using ( var cmd =  new SqlCommand( " sp_insert_jk_users ", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
         /// / Adding a "structured" parameter allows you to insert tons of data with low overhead
         var param =  new SqlParameter( " @userTable ", SqlDbType.Structured) { Value = dt };
        cmd.Parameters.Add(param);
        cmd.ExecuteNonQuery();
    }
}
sw.Stop(); 
  現在,我們重新執行寫入操作發現寫入效率與SqlBulkCopy相當。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM