技术方案一:
利用数据库访问类调用存储过程,利用循环逐条插入。很明显,这种方式效率并不高。
技术方案二:
由于是考虑到大数据量的批量插入,于是想到了ADO.NET2.0的一个新的特性:SqlBulkCopy。有关这个的性能,很早之前我亲自做过性能测试,效率非常高。这也是我推荐的技术方案。
技术方案三:
利用SQLServer2008的新特性--表值参数(Table-Valued Parameter)。表值参数是SQLServer2008才有的一个新特性,使用这个新特性,我们可以把一个表类型作为参数传递到函数或存储过程里。不过,它也有一个特点:表值参数在插入数目少于 1000 的行时具有很好的执行性能。
技术方案四:
对于单列字段,可以把要插入的数据进行字符串拼接,最后再在存储过程中拆分成数组,然后逐条插入。查了一下存储过程中参数的字符串的最大长度,然后除以字段的长度,算出一个值,很明显是可以满足要求的,只是这种方式跟第一种方式比起来,似乎没什么提高,因为原理都是一样的。
技术方案五:
考虑异步创建、消息队列等等。这种方案无论从设计上还是开发上,难度都是有的。
优势对比:
方案一的效率最低,需要多次更新数据库,方案四与方案一原理相同,只是将处理放到了存储过程中,且在参数传入前后需进行拼接和拆分,操作比较麻烦。用SQL2008数据库时推荐使用方案四。
对比方案一、二、三,技术方案二的优势还是蛮高的。无论是从通用性还是从性能上考虑,都应该是优先被选择的,另外它的技术复杂度要比技术方案三要简单一些,设想我们把所有表都创建一遍表值类型,工作量还是很大。
因此推荐大家使用第二种技术方案。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #region 批量插入数据到数据库
2 DateTime startTime;
3 privatebool SqlBulkCopy(DataTable dt)
4 {
5
6 try
7 {
8 startTime = DateTime.Now;
9 //数据批量导入sqlserver,创建实例 SqlBulkCopyOptions.UseInternalTransaction采用事务 复制失败自动回滚
10 System.Data.SqlClient.SqlBulkCopy sqlbulk =new System.Data.SqlClient.SqlBulkCopy(System.Configuration.ConfigurationSettings.AppSettings["ConStr"], SqlBulkCopyOptions.UseInternalTransaction);
11 sqlbulk.SqlRowsCopied +=
12 new SqlRowsCopiedEventHandler(OnRowsCopied); //订阅复制完成后的方法,参数是 sqlbulk.NotifyAfter的值
13 sqlbulk.NotifyAfter = dt.Rows.Count;
14
15 //目标数据库表名
16 sqlbulk.DestinationTableName ="T_TempUpLoadTC";
17 //数据集字段索引与数据库字段索引映射
18 sqlbulk.ColumnMappings.Add(0, "userName");
19 sqlbulk.ColumnMappings.Add(1, "JiFenCount");
20 //导入
21 sqlbulk.WriteToServer(dt);
22 sqlbulk.Close();
23 returntrue;
24 }
25 catch (Exception ex)
26 {
27 thrownew Exception(ex.Message);
28 }
29 finally
30 {
31 dt.Dispose();
32 }
33 }
34
35
36 //复制完成后的处理事件
37 privatevoid OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
38 {
39 lblCounter.Text += args.RowsCopied.ToString() +" 条记录已导入";
40 TimeSpan copyTime = DateTime.Now - startTime;
41 lblCounter.Text +=" 花费时间:"+ copyTime.Seconds.ToString() +"."+
42 copyTime.Milliseconds.ToString() +" 秒";
43 }
44 #endregion
45
2 DateTime startTime;
3 privatebool SqlBulkCopy(DataTable dt)
4 {
5
6 try
7 {
8 startTime = DateTime.Now;
9 //数据批量导入sqlserver,创建实例 SqlBulkCopyOptions.UseInternalTransaction采用事务 复制失败自动回滚
10 System.Data.SqlClient.SqlBulkCopy sqlbulk =new System.Data.SqlClient.SqlBulkCopy(System.Configuration.ConfigurationSettings.AppSettings["ConStr"], SqlBulkCopyOptions.UseInternalTransaction);
11 sqlbulk.SqlRowsCopied +=
12 new SqlRowsCopiedEventHandler(OnRowsCopied); //订阅复制完成后的方法,参数是 sqlbulk.NotifyAfter的值
13 sqlbulk.NotifyAfter = dt.Rows.Count;
14
15 //目标数据库表名
16 sqlbulk.DestinationTableName ="T_TempUpLoadTC";
17 //数据集字段索引与数据库字段索引映射
18 sqlbulk.ColumnMappings.Add(0, "userName");
19 sqlbulk.ColumnMappings.Add(1, "JiFenCount");
20 //导入
21 sqlbulk.WriteToServer(dt);
22 sqlbulk.Close();
23 returntrue;
24 }
25 catch (Exception ex)
26 {
27 thrownew Exception(ex.Message);
28 }
29 finally
30 {
31 dt.Dispose();
32 }
33 }
34
35
36 //复制完成后的处理事件
37 privatevoid OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
38 {
39 lblCounter.Text += args.RowsCopied.ToString() +" 条记录已导入";
40 TimeSpan copyTime = DateTime.Now - startTime;
41 lblCounter.Text +=" 花费时间:"+ copyTime.Seconds.ToString() +"."+
42 copyTime.Milliseconds.ToString() +" 秒";
43 }
44 #endregion
45