连接未关闭,foreach循环中Connection's当前状态为打开错误

本文关键字:状态 错误 foreach Connection 循环 连接 | 更新日期: 2023-09-27 18:03:33

我有一个使用绑定复选框列表的web应用程序。我在foreach循环中放置了一个更新存储过程。如果选中了一个CheckboxList,则更新正常,但如果选中了多个,则会抛出连接打开错误。我尝试了try{}catch{}finally{},但它仍然给我相同的错误

CultureInfo provider = CultureInfo.InvariantCulture;
System.Globalization.DateTimeStyles style = DateTimeStyles.None;
DateTime dt;
DateTime.TryParseExact(datepicker.Text, "mmddy", provider, style, out dt);
int i = Int32.Parse(amount.Text);
SqlConnection conn = new SqlConnection(GetConnectionString());
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;

 foreach (ListItem item in CheckBoxList1.Items)
 {
     if(item.Selected)
     {
          cmd.CommandType = CommandType.StoredProcedure;
          cmd.CommandText = "[dbo].[AccountCode_Update]";
          cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i;
          cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt;
          cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue;
          conn.Open();
          cmd.ExecuteNonQuery();
     }

  }
  conn.Close();
SQL

CREATE TABLE AccountTable
(
  RowID int IDENTITY(1, 1),
  AccountID varchar(2),
  AccountName varchar(50),
  SeqNum int,
  SeqDate datetime
)
CREATE PROCEDURE [AccountCode_Update]
(
  @Batch_Num int,
  @Batch_Date datetime,
  @Account_Code varchar(2)
)
 AS 
 SET NOCOUNT ON
 BEGIN
  UPDATE AccountTable
   SET SeqNum = @Batch_Num, SeqDate = @Batch_Date
   WHERE AccountID = @Account_Account_Code
 END

连接未关闭,foreach循环中Connection's当前状态为打开错误

conn.Open();调用移到foreach循环之前

SqlConnection conn = new SqlConnection(GetConnectionString());
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
conn.Open();
foreach (ListItem item in CheckBoxList1.Items)
{
    if(item.Selected)
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "[dbo].[AccountCode_Update]";
        cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i;
        cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt;
        cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue;
        cmd.ExecuteNonQuery();
    }
}
conn.Close();

发生的事情是,你正在调用一个已经打开的连接的conn.Open(),它抛出一个错误。这就是为什么第一次调用成功,而接下来的调用失败的原因。

查看Open()方法的MSDN文档。它有一些会导致异常的例子。

在本例中

InvalidOperationException

不能在未指定数据源或服务器的情况下打开连接。或连接已打开

关闭连接!此外,您还需要清除每个循环中的命令参数。

 foreach (ListItem item in CheckBoxList1.Items)
 {
     if(item.Selected)
     {
          cmd.CommandType = CommandType.StoredProcedure;
          cmd.CommandText = "[dbo].[AccountCode_Update]";
          cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i;
          cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt;
          cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue;
          conn.Open();
          cmd.ExecuteNonQuery();
          conn.Close();
          cmd.Parameters.Clear(); // you need to clear previous parameters
     }

  }

更新: OK。我看到了@Krik的答案,我需要描述一下:

使用ADO的基本规则之一。. NET是这样的:尽可能晚地打开连接,并尽可能快地关闭连接。因此,您不应该通过循环保持打开的连接,因为您在这里执行一些与数据库无关的操作。例如清除命令的参数并重新填充它。因此,这将是理想的:

conn.Open();
cmd.ExecuteNonQuery();
conn.Close();

一旦打开。