在.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,1) primary key,
adesc varchar(50) not 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