已经有一个打开的DataReader与此命令关联,必须先关闭它.请帮帮我

本文关键字:关联 有一个 DataReader 命令 | 更新日期: 2023-09-27 18:27:46

public void StockUpdate()
{
    cmd5 = new SqlCommand("select * from SupplierBillSelection where purordentryid=" + txtPurEntryID.Text + "", con);
    var dr1 = cmd5.ExecuteReader();
    if (dr1.HasRows)
    {
        while (dr1.Read())
        {
             cmd2 = new SqlCommand("select * from Stock where ItemName='" + dr1[2].ToString() + "'", con);
             dr5 = cmd2.ExecuteReader();
            if (dr1.HasRows)
            {
                if (dr5.HasRows)
                {
                    dr5.Read();
                    string insert = "Update Stock set Quantity=" + (Convert.ToSingle(dr5[13]) + Convert.ToSingle(dr1[15])) + " ,TotalPrice=" + (Convert.ToSingle(dr5[14])+Convert.ToSingle(dr1[16]))+ " where ItemName='" + dr1[1].ToString() + "'and CompanyName='" + dr1[2].ToString() +"'";
                    cmd3 = new SqlCommand(insert, con);
                    Console.WriteLine(insert);

已经有一个打开的DataReader与此命令关联,必须先关闭它.请帮帮我

出现此异常的原因是,您最终在一个连接上拥有多个结果集。换言之,打开第二个SqlDataReader,而第一个仍然处于活动状态。

要解决此问题,您必须重写查询以使用joins,或者如果可用,启用MARS。不过,我非常确信,将整个代码块重写为单个UPDATE FROM SELECT是完全可能的。

此外,您还面临着一系列常见的问题,如未正确处理可丢弃对象、使用select *、连接SQL语句和信任用户输入。

在连接字符串中添加此"MultipleActiveResultSets=True;"。

我认为你没有发布所有的代码,但通常情况下,如果你像这样调用ExecuteReader,你必须在阅读器上调用Close()。唯一的例外是使用"使用块"。Using Block在内部调用dispose并自动关闭读取器。

您应该以这种方式使用DataReader

using(DataReader dr1 = cmd5.ExecuteReader(CommandBehavior.CloseConnection)
{
    //do stuff here
}

Sangram-Kakade的回答应该允许您运行代码,但我建议不要这样编码查询。第一个查询中的每一行都将在第二个读取器中生成一个额外的插入或更新,并且您将洪泛服务器。

考虑使用MERGE,因为它以更快、原子化的方式完成工作(默认情况下,所有插入和更新都在隐式事务中执行)。

相关文章: