已经有一个与此命令关联的打开的 DataReader,必须先将其关闭。请帮帮我
There is already an open DataReader associated with this Command which must be closed first. please help me out
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);
你得到这个异常的原因是你最终在一个连接上有多个结果集。换句话说,您打开第二个 SqlDataReader
,而第一个仍然处于活动状态。
要解决此问题,您必须重写查询以使用 join
,或者如果可用,enable MARS. I'm more than sure, though, that it is quite possible to rewrite this entire code block as a single UPDATE FROM SELECT.
此外,您还遇到了一系列常见问题,例如未正确处理一次性物品、使用 select *
、连接 SQL 语句和信任用户输入。
我认为您没有 post 所有代码,但一般来说,如果您像现在这样调用 ExecuteReader,则必须在 reader 上调用 Close()。唯一的例外是如果您使用 Using-Blocks。 Using-Block 调用内部处理并自动关闭 reader.
在连接字符串中添加 "MultipleActiveResultSets=True;"。
您应该这样处理您的 DataReader
:
using(DataReader dr1 = cmd5.ExecuteReader(CommandBehavior.CloseConnection)
{
//do stuff here
}
Sangram Kakade 的回答应该允许您 运行 您的代码,但我建议不要像这样对您的查询进行编码。第一个查询中的每一行都会在第二个查询中生成额外的插入或更新 reader 并且您将淹没服务器。
考虑使用 MERGE,因为它以原子方式更快地完成工作(默认情况下,所有插入和更新都在隐式事务中执行)。
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);
你得到这个异常的原因是你最终在一个连接上有多个结果集。换句话说,您打开第二个 SqlDataReader
,而第一个仍然处于活动状态。
要解决此问题,您必须重写查询以使用 join
,或者如果可用,enable MARS. I'm more than sure, though, that it is quite possible to rewrite this entire code block as a single UPDATE FROM SELECT.
此外,您还遇到了一系列常见问题,例如未正确处理一次性物品、使用 select *
、连接 SQL 语句和信任用户输入。
我认为您没有 post 所有代码,但一般来说,如果您像现在这样调用 ExecuteReader,则必须在 reader 上调用 Close()。唯一的例外是如果您使用 Using-Blocks。 Using-Block 调用内部处理并自动关闭 reader.
在连接字符串中添加 "MultipleActiveResultSets=True;"。
您应该这样处理您的 DataReader
:
using(DataReader dr1 = cmd5.ExecuteReader(CommandBehavior.CloseConnection)
{
//do stuff here
}
Sangram Kakade 的回答应该允许您 运行 您的代码,但我建议不要像这样对您的查询进行编码。第一个查询中的每一行都会在第二个查询中生成额外的插入或更新 reader 并且您将淹没服务器。
考虑使用 MERGE,因为它以原子方式更快地完成工作(默认情况下,所有插入和更新都在隐式事务中执行)。