使用套件SqlBulkCopy 有效率地將其他來源的資料大量載入 SQL Server 資料表.
最近維護專案, 看到前輩使用SqlBulkCopy , 大概知道是對DB做資料存取的, 如果只是一般的資料存取用 SqlCommand.ExecuteNonQuery 一筆一筆做掉不就好了嗎??
後來查詢了一下MSDN, 如下:
類別 | 描述 | |
---|---|---|
SqlBulkCopy |
可讓您有效率地大量載入具有另一個來源的資料之 SQL Server 資料表。 |
若需要批次更新大筆資料的時候使用此套建可以大幅增進效能.
這也是微軟家的東西,
命名空間: System.Data.SqlClient
組件: System.Data (在 System.Data.dll 中)
請安心服用.
簡單的程式範例如下:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Transactions;
public partial class test_sqlBulkCopy : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
//產生source table
DataTable sourceDt = new DataTable();
sourceDt.Columns.Add("id", typeof(int));
sourceDt.Columns.Add("colA", typeof(string));
sourceDt.Columns.Add("colB", typeof(string));
sourceDt.Columns.Add("colC", typeof(string));
//看你要產生幾筆row先寫在datatable
for (int i = 0; i < 100; i++)
{
DataRow dr = sourceDt.NewRow();
dr["colA"] = "a" + i.ToString();
dr["colB"] = "b" + i.ToString();
dr["colC"] = "c" + i.ToString();
sourceDt.Rows.Add(dr);
}
//加入2.0以後的交易,記得匯入System.Transactions.dll
using (TransactionScope myScope = new TransactionScope())
{
//大量寫入
using (SqlConnection myConn = new SqlConnection(ConfigurationManager.
ConnectionStrings["NORTHWNDConnectionString"].ConnectionString))
{
myConn.Open();
using (SqlBulkCopy testSbc = new SqlBulkCopy(myConn))
{
//設定
testSbc.BatchSize = 1000;
testSbc.BulkCopyTimeout = 60;
//處理完委派事件,可寫可不寫,在複製過程會觸發testSbc_SqlRowsCopied事件,主要目的是顯示訊息讓使用者了解目前的進度。
testSbc.NotifyAfter = sourceDt.Rows.Count;
testSbc.SqlRowsCopied += new SqlRowsCopiedEventHandler(testSbc_SqlRowsCopied);
//更新資料庫名稱
testSbc.DestinationTableName = "dbo.test";
//column對應
testSbc.ColumnMappings.Add("id", "id");
testSbc.ColumnMappings.Add("colA", "a");
testSbc.ColumnMappings.Add("colB", "b");
testSbc.ColumnMappings.Add("colC", "c");
//寫入資料
testSbc.WriteToServer(sourceDt);
//完成交易
myScope.Complete();
}
}
}
}
void testSbc_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
{
ClientScript.RegisterStartupScript(GetType(), "test", "alert('完成');", true);
}
}
據說若兩邊連線沒有異常, DB本身loading也沒有爆炸, 幾十萬筆資料可以一秒內就跑完.
用了很久才發現他是很不錯的東西呀. 筆記先.
參考:
https://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx
http://msdn2.microsoft.com/zh-tw/library/system.data.sqlclient.sqlbulkcopy(VS.80).aspx
http://msdn2.microsoft.com/zh-tw/library/system.transactions.transactionscope.aspx