连接未关闭,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
将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();
一旦打开。