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();
}