Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 哪个dr处于打开状态?(System.InvalidOperationException:';已存在与此命令关联的打开的数据读取器,必须先关闭该读取器。';)_C#_Visual Studio - Fatal编程技术网

C# 哪个dr处于打开状态?(System.InvalidOperationException:';已存在与此命令关联的打开的数据读取器,必须先关闭该读取器。';)

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

我得到了下面的验证(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(); 
    }

您的代码有很多问题:

  • 您的主要问题是:没有从第一个命令中处理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);
}
}

在执行第二条命令之前关闭读卡器—您从未处理过的命令。始终使用块处置连接和读卡器对象顺便说一句,您可以省去两个命令,在一个批处理中完成,并使用适当的参数化,您当前的代码很容易被注入