2017-08-07 70 views
-1

我有2个SqlCommand,其中之一嵌套。为什么它不允许我发出第二个SqlCommand(我正在使用单独的SQLCommand)?它给出错误“已经有一个与此命令关联的打开的DataReader,必须先关闭”。 。如果我使用单独的SqlConnection,那很好。不允许嵌套SQLCommand?

SqlCommand cmd = new SqlCommand(qry, cn); 

SqlDataReader rd = cmd.ExecuteReader(); 

while (rd.Read()) 
{ 
     ....  
     try 
     { 
      SqlCommand cmd2 = new SqlCommand(qry2, cn); 
      cmd2.ExecuteNonQuery(); 
     } 
     catch (Exception e) 
     { 
      // I get this error here 
      // System.Data; There is already an open DataReader associated with this Command which must be closed first. 
     }   
} 
+1

您需要额外的连接实例才能为同时查询执行具有相同连接字符串的另一个查询。由于在执行另一个查询时可能无法停止DataReader,所以考虑将DataReader内容拉到DataTable中关闭第一个连接并在迭代DataTable内容时重新打开。 –

回答

1

的信息是明显的:你不能在同一时间使用不同SqlCommand例如相同的连接而DataReader仍处于打开状态。该SqlDataReader实例说明已经说了:

当正在使用SqlDataReader对象时,关联的SqlConnection是 忙于服务SqlDataReader中,和没有其他操作可以在比关闭它其他的SqlConnection来 执行。 的情况就是这种情况,直到SqlDataReader的Close方法被调用。例如, 直到调用关闭之后才能检索输出参数。

此问题的常见解决方案是在连接字符串中使用MultipleActiveResultSets=True

<add name="ConnectionName" connectionString="[connection string];MultipleActiveResultSets=True" ... /> 

然后,使用DataTable代替迭代DataReader直接:

var dt = new DataTable(); 
dt.Load(rd); 

foreach (DataRow row in dt.Rows) 
{ 
    // other stuff 

    try 
    { 
     SqlCommand cmd2 = new SqlCommand(qry2, cn); 
     cmd2.ExecuteNonQuery(); 
    } 
    catch (Exception e) 
    { 
     // throw exception 
    } 
} 

此外,你可以把简单的检查,如果以前的连接仍然开放(即服务DataReader)使用SqlConnection.State财产:

// close if connection still open 
if (cn.State == ConnectionState.Open) 
{ 
    cn.Close(); 
} 

// open if connection already closed 
if (cn.State == ConnectionState.Closed) 
{ 
    cn.Open(); 
} 

上面的简单检查应放在请求SqlConnection的代码的任何部分。

+0

感谢您的明确解释 – Squirrel