2017-02-03 3 views
0

Ich habe einen try \ catch-Block, der das Öffnen einer Verbindung und das Einfügen von Daten in eine Datenbank behandelt.Umgang mit einem Array von SQL-Fehlercodes

catch (SqlException ex) 
      { 
       string sqlError = null; 
       for (int i = 0; i < ex.Errors.Count; i++) 
       { 
        sqlError += "Error Message " + ex.Errors[i].Message + "\n" + "Stored Procedure " + ex.Errors[i].Procedure + " \n " + "Line Number " + ex.Errors[i].LineNumber; 
       } 
       LogTools.WriteLog("Sql Server error " + sqlError); 
       Variables.InstallStatusDetail = "Database connection failed"; 

       if (!sqlError.Contains("connection to SQL Server")) 
       { 
        if (Variables.WriteToDatabase) 
        { HostedDataBase.InsertRunStatusIntoInstallStatus('E', sqlError, null); } 
       } 
      } 

Ich möchte SQLExceptions in die Datenbank protokollieren, wird nicht mit Verbindungs ​​und Protokollierung in die Datenbank stören. Das Problem tritt auf, wenn die Datenbank nicht gefunden werden kann oder eine Anmeldung nicht über die erforderlichen Berechtigungen usw. verfügt. Die Ausnahme wird ausgelöst und versucht, sich bei der Datenbank anzumelden. Wenn sie dies tut, ruft sie die Funktion auf, die in die Datenbank schreibt Datenbank und versucht erneut auf sie zuzugreifen, aber erneut wird die gleiche Ausnahme ausgelöst, was zu einer Schleife fehlgeschlagener Versuche führt, in die Datenbank zu schreiben (entweder, weil der DSN nicht gefunden werden kann oder der Benutzer nicht über die entsprechenden Berechtigungen verfügt).

Wie kann ich SQL-Fehler behandeln, die mich daran hindern würden, auf die Datenbank zuzugreifen und sie zu schreiben und gleichzeitig SQL-Fehler zu schreiben, die diese Schleife nicht verursachen würden?

Antwort

0

Ich bin etwas verwirrt durch Ihre Frage, aber ich werde versuchen, sie zu beantworten. Sie müssen vorsichtig sein mit dem Umgang mit Ausnahmen. Wenn Sie versuchen, die Verbindung zur Datenbank wiederherzustellen, obwohl eine Ausnahme zum ersten Mal ausgelöst wurde, möchten Sie möglicherweise einige Bedingungen überprüfen, welche Art von Ausnahme ausgelöst wurde. Auf diese Weise wissen Sie, dass Sie nur versuchen, die Verbindung wiederherzustellen, wenn es sich um eine Ausnahme handelt, die nicht immer wieder wiederholt wird.

IE.

catch (SqlException ex) 
       { 
         Error = ex.ToString() 
         WriteToLog(Error); 
         CheckError(); 

       } 

    Void CheckError() 
    { 
    //conditions based on error output. 
    } 

void WriteToLog(string Error) 
{ 
// write your error output to log 
} 
+0

Entschuldigung für die vage Frage. Ich möchte alle Fehler (einschließlich einiger SQL-Fehler) in der Datenbank protokollieren. Das Problem liegt vor, wenn eine Ausnahme darauf zurückzuführen ist, dass das Programm den DSN nicht finden kann oder keine Berechtigungen hat. Der Code wird erneut ausgeführt und führt zu einer Schleife von versuchten Einfügungen in etwas, das nicht gefunden werden kann oder nicht über die entsprechenden Berechtigungen verfügt. Ich möchte eine pragmatische Art und Weise überprüfen, bevor wir versuchen, einen Fehler einzufügen, ist der SQL-Fehler etwas, das das Schreiben in die Datenbank nicht stören würde (wie eine schlechte Verbindung oder ein Benutzer mit unzulässigen Berechtigungen). – Mattaceten

+0

Es klingt wie Ihre beste Route wäre, eine Art Zähler zu erstellen, der die Verbindungsversuche verfolgt und Ihre Schleife unterbricht, wenn Sie beispielsweise 5 erreichen. Wenn es 5 Mal gescheitert ist, wird es wahrscheinlich nicht funktionieren. Erstellen Sie einfach einen INT und erhöhen Sie ihn bei jedem Verbindungsversuch. –

+0

Ihr Beispiel ist sinnvoll, aber gibt es einen Weg in der CheckError-Methode zu sagen, ob der SQL-Fehler eine schlechte Verbindung oder schlechte Berechtigungen ist? Oder eine ganze Liste unbekannter Fehler, die den Datenbankzugriff behindern könnten? Offensichtlich, wenn die Datenbank nicht zugegriffen werden kann, sollte nicht versucht werden, etwas einzufügen – Mattaceten

0

Sie sollten die Protokollierung in einem eigenen try..catch Block, so:

catch (SqlException ex) 
{ 
    string sqlError = null; 
    for (int i = 0; i < ex.Errors.Count; i++) 
    { 
     sqlError += "Error Message " + ex.Errors[i].Message + "\n" + "Stored Procedure " + ex.Errors[i].Procedure + " \n " + "Line Number " + ex.Errors[i].LineNumber; 
    } 
    LogTools.WriteLog("Sql Server error " + sqlError); 
    Variables.InstallStatusDetail = "Database connection failed"; 

    if (!sqlError.Contains("connection to SQL Server")) 
    { 
     if (Variables.WriteToDatabase) 
     { 
      try { 
       //I am assuming this is where you are trying to write the error back into the database 
       HostedDataBase.InsertRunStatusIntoInstallStatus('E', sqlError, null); 
      } catch { 
       //ignore errors here 
      } 
     } 
    } 
} 
0

Leider, wenn Sie auf die gleiche Datenbank schreiben, die Sie haben keinen Zugang zu, ich Ich fürchte, du kannst das nicht tun.

Ich würde vorschlagen, dass Sie etwas wie Log4net verwenden, die mehrere Appender (Eventlog, Datenbank, Datei, etc) haben kann. Außerdem funktioniert log4net so etwas wie ein Feuer und vergisst es. Auch wenn log4net Probleme beim Protokollieren der Fehler hat, werden keine Ausnahmen ausgelöst.

Verwandte Themen