zoukankan      html  css  js  c++  java
  • 批量插入数据利器之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)

  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/yf2011/p/4465687.html
Copyright © 2011-2022 走看看