2017-08-07 6 views
-1

Ich habe 2 SqlCommand, einer von ihnen ist verschachtelt. Warum kann ich den zweiten SqlCommand nicht ausgeben (ich verwende einen separaten SQLCommand)? Es gibt Fehler "Es ist bereits ein offener DataReader mit diesem Befehl verbunden, der zuerst geschlossen werden muss." . Wenn ich eine separate SqlConnection verwende, ist das in Ordnung.Nested SQLCommand nicht zulassen?

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

Sie benötigen eine zusätzliche Verbindungsinstanz, um eine weitere Abfrage mit derselben Verbindungszeichenfolge für gleichzeitige Abfragen auszuführen. Da es unmöglich ist, "DataReader" beim Ausführen einer anderen Abfrage zu stoppen, ziehen Sie in Erwägung, "DataReader" -Inhalte in eine "DataTable" zu ziehen, die erste Verbindung zu schließen und beim Iterieren von 'DataTable'-Inhalten erneut zu öffnen. –

Antwort

1

Die Botschaft ist klar: Sie nicht gleiche Verbindung für verschiedene SqlCommand Instanz zur gleichen Zeit verwenden können, während DataReader noch offen sind. Die SqlDataReader Beispiel Erklärung bereits gesagt, dass:

Während die SqlDataReader verwendet wird, die damit verbundene SqlConnection beschäftigt ist, die SqlDataReader dient, und keine anderen Operationen auf der SqlConnection durchgeführt werden kann, anders als es schließen. Dies ist der Fall bis die Close-Methode des SqlDataReader aufgerufen wird. Zum Beispiel können Sie Ausgabeparameter erst abrufen, nachdem Sie Close aufgerufen haben.

Die gemeinsame Lösung für dieses Problem wird mit MultipleActiveResultSets=True auf Verbindungszeichenfolge:

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

Dann DataTable, verwenden Sie stattdessen DataReader Iterieren direkt: Zusätzlich

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 
    } 
} 

, können Sie einfache Überprüfung stellen, wenn Die vorherige Verbindung ist noch offen (dh DataReader) mit SqlConnection.State Eigenschaft:

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

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

Die obigen einfachen Überprüfungen sollten an jedem Teil des Codes vorgenommen werden, der SqlConnection anfordert.

+0

Danke für die klaren Erklärungen – Squirrel