我有一个使用数据绑定列表的网络应用程序。我有一个更新存储过程,我放在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
答案 0 :(得分:5)
在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 documentation。它有一些导致异常的例子。
在这种情况下
<强>出现InvalidOperationException 强>
如果未指定数据源或服务器,则无法打开连接。 要么 此连接已打开。
答案 1 :(得分:2)
关闭连接!此外,您需要在每个循环中清除命令参数。
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
}
}
更新:确定。我看到@Krik的回答,我需要描述一下:
使用ADO.NET的基本规则之一是:尽可能地打开连接,并尽快关闭它。所以,你不应该保持打开状态通过循环连接,因为你在这里做了一些与数据库无关的操作。如清除命令的参数并重新填充它。所以,这将是理想的:
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
答案 2 :(得分:1)
conn.Open应该在foreach之外。
一旦打开。它试图再次打开第二项。选择。