c# - 哪个博士是打开的?(System.InvalidOperationException:'已经有一个打开的 DataReader 与此命令关联,必须先关闭。')
问题描述
我收到了以下异常(System.InvalidOperationException:'已经有一个打开的 DataReader 与此命令关联,必须先关闭。')我不知道如何修复它。我会感谢一些帮助
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();
}
解决方案
您的代码存在许多问题:
- 您的主要问题:不从第一个命令中处理阅读器对象
- 出于同样的原因,您还在连接仍处于打开状态时使用消息框阻止线程
- 您将用户输入直接插入到查询中,这使您容易受到注入攻击和语法错误的影响。确保您不这样做的一个好方法是将批次存储在
const string
- 您的更新查询还有额外的
'
引号,它们是语法错误 productid
不是字符串,在这种情况下,无论如何您都不应该将其括在引号中- 如果你
int
从读者那里得到一个结果,你不应该把它字符串化,然后再次解析它int.Parse(dr.GetValue(0).ToString())
,而不是转换它(int) dr.GetValue(0)
(你可能还想检查一下DBNull
) - 如果结果中只有一行和一列,则可以使用
ExecuteScalar
- 您可以将这两个查询合并为一个,并为自己节省两批的往返行程
- 您在代码中嵌入了连接字符串,它应该保存在设置文件中
private void button2_Click(object sender, EventArgs e) // PLACING ORDERS
{
int rowcount;
const string query = @"
UPDATE Production.ProductInventory
SET Quantity -= @qty
WHERE ProductId = @productId
AND Quantity >= @qty;
";
using (SqlConnection con = new SqlConnection(Properties.Settings.ConnectionString))
using (SqlCommand cmd1 = new SqlCommand(query,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();
}
if(rowcount == 0)
{
MessageBox.Show("Unfortunately we are not able to provide you with the amount you want", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
推荐阅读
- c# - 从 C# 中的 Rust DLL 获取 UTF-8 编码的字符串
- java - 我的 Android Studio 项目中的运行时错误是什么?
- python - 从列表中选择值 - 如何提高效率
- r - r2d3中的动态变量选择
- javascript - 在 p5js 中获取图像的像素值
- kubernetes - 如何在 Kubernetes 上自定义 config.toml?
- react-native - 如何在 react-native 中设置 Onpress On Textinput
- google-maps - 角度 agm 核心地图圈单击未打开 agm 信息窗口
- python - 根据重复模式捕获整个重复字符串
- c# - Crystal Report CSV Generation