批量插入数据利器之SqlBulkCopy

工作中要频繁的处理一些数据导入,又不想手工去做,因此用了神器SqlBulkCopy。在MSDN查看了此类的帮助文档几经波折终于搞定,记录下来方便以后查阅。

MSDN实例:

 1 using System.Data.SqlClient;
 2 
 3 class Program
 4 {
 5     static void Main()
 6     {
 7         string connectionString = GetConnectionString();
 8         // Open a sourceConnection to the AdventureWorks database.
 9         using (SqlConnection sourceConnection =
10                    new SqlConnection(connectionString))
11         {
12             sourceConnection.Open();
13 
14             // Perform an initial count on the destination table.
15             SqlCommand commandRowCount = new SqlCommand(
16                 "SELECT COUNT(*) FROM " +
17                 "dbo.BulkCopyDemoMatchingColumns;",
18                 sourceConnection);
19             long countStart = System.Convert.ToInt32(
20                 commandRowCount.ExecuteScalar());
21             Console.WriteLine("Starting row count = {0}", countStart);
22 
23             // Get data from the source table as a SqlDataReader.
24             SqlCommand commandSourceData = new SqlCommand(
25                 "SELECT ProductID, Name, " +
26                 "ProductNumber " +
27                 "FROM Production.Product;", sourceConnection);
28             SqlDataReader reader =
29                 commandSourceData.ExecuteReader();
30 
31             // Open the destination connection. In the real world you would 
32             // not use SqlBulkCopy to move data from one table to the other 
33             // in the same database. This is for demonstration purposes only.
34             using (SqlConnection destinationConnection =
35                        new SqlConnection(connectionString))
36             {
37                 destinationConnection.Open();
38 
39                 // Set up the bulk copy object. 
40                 // Note that the column positions in the source
41                 // data reader match the column positions in 
42                 // the destination table so there is no need to
43                 // map columns.
44                 using (SqlBulkCopy bulkCopy =
45                            new SqlBulkCopy(destinationConnection))
46                 {
47                     bulkCopy.DestinationTableName =
48                         "dbo.BulkCopyDemoMatchingColumns";
49 
50                     try
51                     {
52                         // Write from the source to the destination.
53                         bulkCopy.WriteToServer(reader);
54                     }
55                     catch (Exception ex)
56                     {
57                         Console.WriteLine(ex.Message);
58                     }
59                     finally
60                     {
61                         // Close the SqlDataReader. The SqlBulkCopy
62                         // object is automatically closed at the end
63                         // of the using block.
64                         reader.Close();
65                     }
66                 }
67 
68                 // Perform a final count on the destination 
69                 // table to see how many rows were added.
70                 long countEnd = System.Convert.ToInt32(
71                     commandRowCount.ExecuteScalar());
72                 Console.WriteLine("Ending row count = {0}", countEnd);
73                 Console.WriteLine("{0} rows were added.", countEnd - countStart);
74                 Console.WriteLine("Press Enter to finish.");
75                 Console.ReadLine();
76             }
77         }
78     }
79 
80     private static string GetConnectionString()
81         // To avoid storing the sourceConnection string in your code, 
82         // you can retrieve it from a configuration file. 
83     {
84         return "Data Source=(local); " +
85             " Integrated Security=true;" +
86             "Initial Catalog=AdventureWorks;";
87     }
88 }

MSDN 地址:https://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx

自己的测试代码:

 1 /// <summary>
 2         /// 将DataTable表数据插入数据库目标表
 3         /// DataTable Name 和数据库目标表名称一致,DataTable列名为目标数据库目标表字段
 4         /// </summary>
 5         /// <param name="dt">数据源</param>
 6         /// <param name="dbFlag">数据库标识</param>
 7         /// <returns></returns>
 8         public static bool MassInsert(DataTable dt, string dbFlag)
 9         {
10             if (dt == null || dt.Rows.Count == 0)
11             {
12                 Logger.Write("DataTable为空或无填充行", "大数据操作", "");
13                 return false;
14             }
15             if (String.IsNullOrEmpty(dt.TableName))
16             {
17                 Logger.Write("DataTableName为空无法确定目标数据库表", "大数据操作", "");
18                 return false;
19             }
20             SqlConnection con = HelpGetSqlCon(dbFlag);//动态获取SqlConnection对象
21             DateTime time = DateTime.Now;
22             SqlTransaction tra = con.BeginTransaction();//事务
23             SqlBulkCopy sqlBC = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, tra);
24             try
25             {
26                 sqlBC.DestinationTableName = dt.TableName;
27                 //一次批量的插入的数据量
28                 sqlBC.BatchSize = dt.Rows.Count;
29                 sqlBC.WriteToServer(dt);
30                 Logger.Write("【MassInsert】[" + dt.Rows.Count + "]条数据共耗时[" + (DateTime.Now - time).TotalSeconds.ToString() + "]秒", "", ""); //记录日志
31                 tra.Commit();
32                 return true;
33             }
34             catch (Exception ex)
35             {
36                 tra.Rollback();
37                 Logger.WriteException("MassInsert异常", "", ex, "");
38                 return false;
39             }
40             finally
41             {
42                 dt.Clear();
43                 dt.Dispose();
44                 sqlBC.Close();
45                 con.Dispose();
46                 con.Close();
47             }
48         }

以上代码可以插入主键,如果主键重复则事务回滚

正常测试结果:

【2015-04-29 12:49:44】
【MassInsert】[182689]条数据共耗时[3.4911996]秒

主键重复测试结果:

【2015-04-29 12:41:16】

Message:MassInsert异常

Ex.Message:违反了 PRIMARY KEY 约束“PK_AUTHCODES”。不能在对象“dbo.AuthCodes”中插入重复键。重复键值为 (1)。
语句已终止。

Ex.StackTrace: 在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
在 System.Data.SqlClient.SqlBulkCopy.RunParser(BulkCopySimpleResultSet bulkCopyHandler)
在 System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
在 System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
在 System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
在 System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource`1 source)
在 System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource`1 source)
在 System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)
在 System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken)
在 System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
在 System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table)

原文地址:https://www.cnblogs.com/yf2011/p/4465687.html