代码未正确执行时回滚更改

时间:2012-11-02 13:46:05

标签: c# sql

我是SQL新手,在我的项目中,我试图从DataBase表中填充DataSet,然后在DataSet中插入新行。执行此操作后,我再次使用DataSet数据填充Database表。在填写之前,我正在清除或删除数据库表数据。我通过使用以下代码实现了这一点:

Database Table --> myTable
DataSet --> ds

OnButtonClick

   string strQuery = "delete from [dbo].[myTable]"
   SqlConnection conn = new SqlConnection(strConn);
   SqlCommand cmd = new SqlCommand(strQuery, conn);
   SqlCommand command;
   SqlDataAdapter da = new SqlDataAdapter(cmd);
   using (cmd)
   {
      using (conn)
      {
         conn.Open();
         cmd.ExecuteNonQuery();                    //deleting database table data
         foreach (DataRow dr in ds.Tables[0].Rows) //Inserting new data into the Database table
         {
             command = new SqlCommand(InsertQuery, conn);
             command.ExecuteNonQuery();
         }
         conn.Close();
      }
   }

上面的代码工作正常,但是当command sqlCommand中有任何异常时,它会完全删除数据库表而不填充DataSet。有什么修改此代码的建议吗?请帮忙。

更新:

            string strQuery = "delete from [dbo].[myTable]";
            using (SqlCommand cmd = new SqlCommand(strQuery, conn))
            {
                using (SqlCommand cmdReset = new SqlCommand("DBCC CHECKIDENT('myTable', RESEED, 0)", conn))
                {
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
                    conn.Open();
                    SqlTransaction sqlTransaction = conn.BeginTransaction();
                    cmd.Transaction = sqlTransaction;
                    try
                    {
                        cmd.ExecuteNonQuery();                   //deleting database table data
                        cmdReset.ExecuteNonQuery();               //Resetting Identity of first column
                        foreach (DataRow dr in ds.Tables[0].Rows) //Inserting new data into the Database table
                        {
                            command = new SqlCommand(query.createDoctorRow(InsertQuery, conn);
                            command.ExecuteNonQuery();
                        }
                        sqlTransaction.Commit();
                        conn.Close();
                    }
                    catch (Exception e)
                    {
                        sqlTransaction.Rollback();
         /*ERROR*/      throw;  
                    }
                }
            }

  

错误 - > “当分配给命令的连接处于挂起的本地事务中时,ExecuteNonQuery要求命令具有事务。该命令的Transaction属性尚未初始化。”

2 个答案:

答案 0 :(得分:4)

使用事务来运行sql

string strQuery = "delete from [dbo].[myTable]";

using (SqlConnection conn = new SqlConnection(strConn))
{
  using (cmd = new SqlCommand(strQuery, conn))
  {
     SqlDataAdapter da = new SqlDataAdapter(cmd);
     conn.Open();
     SqlTransaction sqlTransaction = conn.BeginTransaction();
     cmd.Transaction = sqlTransaction;
     try
     {
         cmd.ExecuteNonQuery();                    //deleting database table data
         foreach (DataRow dr in ds.Tables[0].Rows) //Inserting new data into the Database table
         {
             command = new SqlCommand(InsertQuery, conn);
             command.ExecuteNonQuery();
         }
         sqlTransaction.Commit();
         conn.Close();
     }
     catch(Exception e)
     {
         sqlTransaction.Rollback();
         throw;
     }
  }

}

交易形成全有或全无的情况。事务中的所有内容都可以工作并提交给数据库,或者整个批次都被取消,好像什么也没发生一样。

答案 1 :(得分:3)

这个example有一个在事务范围中包装sql命令的好方法。基本上,如果在任何行插入期间抛出任何异常,则删除查询也将失败。

在坚果壳中,你将所有东西都包裹在

 using (TransactionScope scope = new TransactionScope())
        {
            using (SqlConnection connection1 = new SqlConnection(connectString1))
            {
                 //enter your code here
            }
      }

此外,您不必逐行插入,您可以使用SqlBulkCopy更有效地执行此操作。

 using (SqlConnection connection =new SqlConnection(connectionString))
 {
        connection.Open();
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
         {                               
                  bulkCopy.DestinationTableName = table.TableName;
                  bulkCopy.WriteToServer(table);
         }
  }