2017-08-07 100 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