轉:SqlBulkCopy批量複製數據

在.Net1.1中無論是對於批量插入整個DataTable中的所有數據到數據庫中,還是進行不同數據源之間的遷移,都不是很方便。而在.Net2.0中,SQLClient命名空間下增加了幾個新類幫助我們通過DataTable或DataReader批量遷移數據。數據源可以來自關係數據庫或者XML文件,甚至WebService返回結果。其中最重要的一個類就是SqlBulkCopy類,使用它可以很方便的幫助我們把數據源的數據遷移到目標數據庫中。
下面我們先通過一個簡單的例子說明這個類的使用:

首先:web.config

 <connectionStrings>
    
<add name="srcDBConnection" connectionString="server=.;database=pubs;uid=sa;pwd="/>
    
<add name="desDBConnection" connectionString="server=.;database=NorthWind;uid=sa;pwd="/>
  
</connectionStrings>

C#文件: 前臺不Copy了,就一個按鈕,一個Label

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class ASP_NET : System.Web.UI.Page
{
    
private DateTime startTime;

    
protected void Button1_Click(object sender, EventArgs e)
    
{
        startTime 
= DateTime.Now;
        
string srcConnString = "";
        
string desConnString = "";
        SqlConnection srcConnection 
= new SqlConnection();
        SqlConnection desConnection 
= new SqlConnection();
        SqlCommand sqlcmd 
= new SqlCommand();
        SqlDataAdapter da 
= new SqlDataAdapter();
        DataTable dt 
= new DataTable();
        
//srcConnString = ConfigurationManager.ConnectionStrings["srcDBConnection"].ConnectionString;
        desConnString = ConfigurationManager.ConnectionStrings["desDBConnection"].ToString();
        
//srcConnection.ConnectionString = srcConnString;
        srcConnection.ConnectionString = desConnString;
        sqlcmd.Connection 
= srcConnection;
        
//sqlcmd.CommandText = "select * from jobs";
        sqlcmd.CommandText = "select * from abc";
        sqlcmd.CommandType 
= CommandType.Text;
        sqlcmd.Connection.Open();
        da.SelectCommand 
= sqlcmd;
        da.Fill(dt);

        SqlBulkCopy sbc 
= new SqlBulkCopy(desConnString,SqlBulkCopyOptions.UseInternalTransaction);
        sbc.BulkCopyTimeout 
= 5000;
        sbc.SqlRowsCopied 
+=new SqlRowsCopiedEventHandler(OnRowsCopied);
        sbc.NotifyAfter 
= dt.Rows.Count;

        
try
        
{
           
// sbc.DestinationTableName = "jobs";
            sbc.DestinationTableName = "bcd";
            sbc.WriteToServer(dt);
        }

        
catch (Exception ex)
        
{
            lblCounter.Text 
= ex.Message.ToString();
        }

        
finally
        
{
            sqlcmd.Clone();
            srcConnection.Close();
            desConnection.Close();
            
        }


    }

    
private void OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
    
{
        lblCounter.Text 
+= args.RowsCopied.ToString() + " rows are copied<Br>";
        TimeSpan copyTime 
= DateTime.Now - startTime;
        lblCounter.Text 
+= "Copy Time:" + copyTime.Seconds.ToString() + "." + copyTime.Milliseconds.ToString() + " seconds";
    }

}

代碼分析:

SqlBulkCopy sbc = new SqlBulkCopy(desConnString,SqlBulkCopyOptions.UseInternalTransaction);
先生成SqlBulkCopy 實例,構造函數指定了目標數據庫,使用SqlBulkCopyOptions.UseInternalTransaction是指遷移動作指定在一個Transaction當中,如果數據遷移中產生錯誤或異常將發生回滾。

sbc.BulkCopyTimeout = 5000000;    //指定操作完成的Timeout時間

 sbc.SqlRowsCopied +=new SqlRowsCopiedEventHandler(OnRowsCopied);
  sbc.NotifyAfter 
= dt.Rows.Count;

        
try
        
{
           
// sbc.DestinationTableName = "jobs";
            sbc.DestinationTableName = "bcd";
            sbc.WriteToServer(dt);
        }

NotifyAfter屬性指定通知通知事件前處理的數據行數,在這裏指定爲表的行數,並添加SqlRowsCopied事件輸出整個遷移過程的時間。WriteToServer方法就是將數據源拷備到目標數據庫。在使用WriteToServer方法之前必須先指定DestinationTableName屬性,也就是目標數據庫的表名,

性能方面:我在Sql中用proc插入68萬條數據花了近8分鐘,用SqlBulkCopy花了53.234秒~,效率高了7倍耶!不過現在也不做這方面的底層了,呵呵,把自己寫的一個測試存儲過程也貼上吧,方便自己學習

create table abc
(
  aid 
int identity(1,1primary key,
  adesc 
varchar(50not null
)
go

/**********存儲過程**********************/
create proc addData
as
declare @i int
set @i=1
while @i < 1000000
begin
insert into abc values ('testDescription')
set @i = @i + 1
end
go

select * into titles from pubs.dbo.titles where  1> 3 複製跨數據庫的表結構
轉自http://blog.csdn.net/huaer1011/archive/2008/04/21/2312361.aspx
發佈了14 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章