在单个事务中发送多个SQL命令

Bic*_*ick 17 .net c# sql-server

我有一个庞大的INSERT INTO ... 字符串列表.目前我运行它们:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    foreach (var commandString in sqlCommandList)
    {
        SqlCommand command = new SqlCommand(commandString, connection);
        command.ExecuteNonQuery();
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到每个ExecuteNonQuery()也执行提交.

  1. 有没有办法在单个事务中插入所有行(最后提交)?
  2. 我想要一个单一事务的原因是让我的"插入"过程更快.单笔交易是否也会更快?

Moh*_*zen 35

如果你在一个线程中执行多个查询,建议使用SQL事务,你可以像这样:

    SqlTransaction trans; 

    try
    {
        SqlConnection connection = new SqlConnection(connectionString);
        connection.Open();

        trans = connection.BeginTransaction(); 

        foreach (var commandString in sqlCommandList)
        {
            SqlCommand command = new SqlCommand(commandString, connection,trans);
            command.ExecuteNonQuery();
        }

        trans.Commit(); 
    }
    catch (Exception ex) //error occurred
    {
        trans.Rollback();
        //Handel error
    }
Run Code Online (Sandbox Code Playgroud)

  • @ Fernando68 >>> SqlCommand command = new SqlCommand(commandString,connection,trans); (2认同)
  • 危险区!没有“使用”意味着泄漏资源。 (2认同)

Ger*_*o H 11

您可能只使用一个事务和命令就可以获得一些性能,如下所示:

using (SqlConnection connection = new SqlConnection(connectionString))
{
   try
   {
      connection.Open();

      using (SqlTransaction trans = connection.BeginTransaction())
      {
          using (SqlCommand command = new SqlCommand("", connection,trans))
          {
             command.CommandType = System.Data.CommandType.Text;

             foreach (var commandString in sqlCommandList)
             {
                command.CommandText = commandString;
                command.ExecuteNonQuery();
             }
          }

          trans.Commit();
       }        
    }
    catch (Exception ex) //error occurred
   {
       //Handel error
   }
}
Run Code Online (Sandbox Code Playgroud)

  • @Tony没有必要调用trans.rollback.如果没有显式提交,SqlTransaction对象将在其Dispose()方法中回滚(例如,如果抛出异常).请参阅以下主题:[为什么使用带有SqlTransaction的using语句?](http://stackoverflow.com/questions/1127830/why-use-a-using-statement-with-a-sqltransaction) (8认同)

Shy*_*hah -2

您可以对每个使用并行

   using (SqlConnection connection = new SqlConnection(connectionString))
    {
        List<string> sqlCommandList = new List<string>();
        connection.Open();
        Parallel.ForEach(sqlCommandList, commandString =>
        {
            SqlCommand command = new SqlCommand(commandString, connection);
            command.ExecuteNonQuery();
        });
    }
Run Code Online (Sandbox Code Playgroud)

  • 1.parallel.foreach 在不同的线程上加载每个事务(每个线程将以提交结束,因此将有相同数量的提交)。2.我尝试过,但插入的顺序有问题。一些插入发生在其他插入之前,并且打破了我的外键限制。不过谢谢:-) (3认同)