C# 哪个dr处于打开状态?(System.InvalidOperationException:';已存在与此命令关联的打开的数据读取器,必须先关闭该读取器。';)
我得到了下面的验证(System.InvalidOperationException:“已经有一个与此命令关联的打开的DataReader,必须先关闭它”),我无法确定如何修复它。我非常感谢你的帮助C# 哪个dr处于打开状态?(System.InvalidOperationException:';已存在与此命令关联的打开的数据读取器,必须先关闭该读取器。';),c#,visual-studio,C#,Visual Studio,我得到了下面的验证(System.InvalidOperationException:“已经有一个与此命令关联的打开的DataReader,必须先关闭它”),我无法确定如何修复它。我非常感谢你的帮助 private void button2_Click(object sender, EventArgs e) // PLACING ORDERS { int qty1 = 0; int cmd2_num; SqlConnection c
private void button2_Click(object sender, EventArgs e) // PLACING ORDERS
{
int qty1 = 0;
int cmd2_num;
SqlConnection con = new SqlConnection("Data Source=.\\sqlexpress;Initial Catalog=adventureworks2012;" + "User ID=sarr**strong *strong text*text**;Password=1234");
con.Open();
SqlCommand cmd1 = new SqlCommand ("select Quantity from Production.ProductInventory where productid ='" + int.Parse(textBox1.Text) + "'",con);
SqlCommand cmd2 = new SqlCommand(
"'UPDATE Production.ProductInventory" +
"SET Quantity -='" + qty +
"'WHERE ProductId = '" + textBox1.Text + "'",con);
SqlDataReader dr = cmd1.ExecuteReader();
while (dr.Read())
{
qty1 = int.Parse(dr.GetValue(0).ToString());
}
if (qty1 >= qty)
{
cmd2_num = cmd2.ExecuteNonQuery();
}
else
{
MessageBox.Show("unfortunatly we are not able to provide you with the amount you want", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
con.Close();
}
您的代码有很多问题:
- 您的主要问题是:没有从第一个命令中处理reader对象
- 出于同样的原因,在连接仍处于打开状态时,您还使用消息框阻止线程
- 您将用户输入直接插入到查询中,这使您容易受到注入攻击和语法错误。确保不这样做的一个好方法是将批存储在
常量字符串中
- 您的更新查询还有额外的
引号,它们是语法错误“
不是字符串,在这种情况下,无论如何都不应将其括在引号中productid
- 如果从读取器获得
结果,则不应将其字符串化,然后再次解析int
只需将其强制转换为int.parse(dr.GetValue(0).ToString())
(您可能还需要检查(int)dr.GetValue(0)
)DBNull
- 如果结果中只有一行和一列,则可以使用
ExecuteScalar
- 您可以将这两个查询合并为一个查询,并节省两个批处理的往返时间
- 如果在代码中嵌入连接字符串,则应将其保存在设置文件中
private void按钮2\u单击(对象发送者,事件参数)//下单
{
整数行数;
常量字符串查询=@“
更新Production.ProductInventory
设置数量-=@数量
其中ProductId=@ProductId
数量>=@数量;
";
使用(SqlConnection con=newsqlconnection(Properties.Settings.ConnectionString))
使用(SqlCommand cmd1=新的SqlCommand(查询,con))
{
cmd1.Parameters.Add(“@productId”,SqlDbType.Int).Value=Int.Parse(textBox1.Text);
cmd1.Parameters.Add(“@qty”,SqlDbType.Int).Value=qty;
con.Open();
rowcount=cmd.ExecuteNonQuery();
}
如果(行计数==0)
{
MessageBox.Show(“很遗憾,我们无法提供您想要的金额”,“哦!”,MessageBoxButtons.OK,MessageBoxIcon.Warning);
}
}
在执行第二条命令之前关闭读卡器—您从未处理过的命令。始终使用块处置连接和读卡器对象顺便说一句,您可以省去两个命令,在一个批处理中完成,并使用适当的参数化,您当前的代码很容易被注入