SqlBulkCopy快速插入大量資料,缺點就是不能查重
相比常用insert語句,在需要插入數十萬百萬資料的時候,利用insert插入的速度相當慢,但其好處就是在可以在插入前進行查重,我們可以寫一個儲存過程,通過判斷插入的資料是否有重複,無則新增有則更新這些操作。但速度也是相當慢,而SqlBulkCopy的速度確實相當快,相比能有幾十倍的速度。這邊我就不說insert怎麼操作了。但SqlBulkCopy的缺點就在於插入資料的時候不能同時進行查重,不知道是否是我沒找到更好的方法。
1,在插入之前,我們可以寫一個方法拼接SqlBulkCopyColumnMapping,如下對應有資料表中的四個欄位。
public SqlBulkCopyColumnMapping[] GetMapping()
{ SqlBulkCopyColumnMapping[] mapping = newSqlBulkCopyColumnMapping[4];
mapping[0] = new SqlBulkCopyColumnMapping("ID", "ID");
mapping[1] = new SqlBulkCopyColumnMapping("Name", "Name");
mapping[2] = new SqlBulkCopyColumnMapping("sex", "sex");
mapping[3] = new SqlBulkCopyColumnMapping("phone", "phone");
return mapping;
}
2,這裡就進行大批量操作,首先我們把大量的資料放在一個datatable上,然後再傳送過來。datatable的行列也要對應資料的欄位。
/// 資料來源
/// 目標表即需要插入資料的資料表名稱如"User_1"
public static bool MySqlBulkCopy(DataTable Table, string DestinationTableName) {
bool Bool = true;
string ConnectionString ="server=localhost;database=10wan;uid=datauser;pwd=1
using (SqlConnection con = new SqlConnection(ConnectionString)) { con.Open();using (SqlTransaction Tran = con.BeginTransaction())//應用事物 { using(SqlBulkCopy Copy = new SqlBulkCopy(con, SqlBulkCopyOptions.KeepIdentity, Tran))
{ Copy.DestinationTableName = DestinationTableName;//指定目標表SqlBulkCopyColumnMapping[] Mapping = GetMapping();//獲取對映關係
if (Mapping != null) {
//如果有資料
foreach (SqlBulkCopyColumnMapping Map in Mapping)
{ Copy.ColumnMappings.Add(Map); }
}
try {
Copy.WriteToServer(Table);
//批量新增
Tran.Commit();
//提交事務
}
catch { Tran.Rollback();//回滾事務 Bool = false; } } } }
return Bool; }
當然也可以將這兩個方法統一起來,如下
///
/// SqlBulkCopy批量插入資料
///
///
public static void InsertDa(DataTable dt)
{
string str= "server=localhost;database=10wan;uid=datauser;pwd=1";
//宣告資料庫連線
SqlConnection conn = new SqlConnection(str);
conn.Open();
//宣告SqlBulkCopy ,using釋放非託管資源
using (SqlBulkCopy sqlBC = new SqlBulkCopy(conn))
{
//一次批量的插入的資料量
//sqlBC.BatchSize = 1000;
//超時之前操作完成所允許的秒數,如果超時則事務不會提交 ,資料將回滾,所有已複製的行都會從目標表中移除
sqlBC.BulkCopyTimeout = 60;
//設定 NotifyAfter 屬性,以便在每插入10000 條資料時,呼叫相應事件。
// sqlBC.NotifyAfter = 10000;
// sqlBC.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);
//設定要批量寫入的表
sqlBC.DestinationTableName = "AirPrices";
//自定義的datatable和資料庫的欄位進行對應
sqlBC.ColumnMappings.Add("ID", "ID");
sqlBC.ColumnMappings.Add("Name", "Name");
sqlBC.ColumnMappings.Add("sex", "sex");
sqlBC.ColumnMappings.Add("phone", "phone");
//批量寫入
sqlBC.WriteToServer(dt);
}
conn.Dispose();
}