6 Stimmen

SQL Server-Fehlerbehandlung: Ausnahmen und der Datenbank-Client-Vertrag

Wir sind ein Team von SQL-Server-Datenbankentwicklern. Unsere Kunden sind eine bunte Mischung aus C#/ASP.NET, C#- und Java-Webdiensten, Java/Unix-Diensten und etwas Excel.

Unsere Kundenentwickler verwenden nur gespeicherte Prozeduren, die wir zur Verfügung stellen, und wir erwarten, dass sie diese (sofern sinnvoll) wie Webdienstmethoden behandeln.

Einige Entwickler unserer Kunden mögen keine SQL-Ausnahmen. Sie verstehen sie in ihren Sprachen, aber sie wissen nicht zu schätzen, dass SQL bei der Kommunikation von Problemen eingeschränkt ist.

Ich meine nicht nur SQL-Fehler, wie z.B. der Versuch, "bob" in eine int-Spalte einzufügen.

Ich meine damit auch Ausnahmen, wie z. B. die Mitteilung, dass ein Referenzwert falsch ist, dass sich die Daten bereits geändert haben oder dass dies nicht möglich ist, weil das Aggregat nicht Null ist.

Sie haben nicht wirklich konkrete Alternativen: Sie haben erwähnt, dass wir Parameter ausgeben sollten, aber wir gehen davon aus, dass eine Ausnahme "Verarbeitung gestoppt/zurückgestellt" bedeutet.

Wie gehen die Leute hier mit dem Datenbank-Client-Vertrag um? Entweder allgemein oder wo es eine Trennung zwischen der DB und Client-Code-Affen.

Bearbeitungen:

  • wir verwenden ausschließlich SQL Server 2005 TRY/CATCH
  • wir protokollieren alle Fehler nach dem Rollback bereits in einer Ausnahmetabelle
  • Wir befürchten, dass einige unserer Kunden die Ausgangsparameter nicht überprüfen und davon ausgehen, dass alles in Ordnung ist. Wir brauchen eine Fehlermeldung, damit der Support sie sich ansehen kann.
  • alles ist eine Ausnahme... von den Clients wird erwartet, dass sie die Nachrichten analysieren, um Informationen von Fehlern zu unterscheiden. Um unsere Ausnahmen von DB-Engine und Aufruffehler zu trennen, sollten sie die Fehlernummer verwenden (unsere sind alle 50.000 natürlich)

3voto

Jon Raynor Punkte 3686

Nun, ich bin ein Client-Code-Affe, der viel mit Datenbanken zu tun hat. Hier ist, wie ich es handhabe.

Ausnahmen (raiseerrors), die in SQL auftreten, werden an den Aufrufer zurückgegeben. Dazu gehören z. B. Ref-Constraints, Verstöße gegen eindeutige Indizes, schwerwiegendere Probleme usw. Grundsätzlich sollte alles, was dazu führt, dass die Datenoperation nicht normal abläuft, zurückgemeldet werden.

Der C#-Aufrufer sollte dies haben:

catch (SQLException sqlEx)

Und behandeln Sie dann die Ausnahme wie erforderlich. Sie sollten einen speziellen SQLException-Handler haben. Dies ist wichtig.

Ich halte mich in der Regel von Ausgabeparametern fern, weil ich der Meinung bin, dass diese mit den zu transportierenden Daten und nicht mit Fehlermeldungen zu tun haben. Außerdem kann ich die Ausnahme auf den SQL-Server-Fehlercode überprüfen, so dass alle benötigten Daten in dieser Ausnahme enthalten sein sollten.

Außerdem haben wir in einigen Fällen mit SQL Server Stored Procedures, die "Business Type of Exceptions" auslösen können. In diesen Fällen fügen wir eine benutzerdefinierte Fehlernummer hinzu (über 50000) und lösen diesen Fehler in der gespeicherten Prozedur bei Bedarf aus. Im Allgemeinen versuchen wir, diese Fehler auf ein Minimum zu beschränken, da sie die Komplexität erhöhen, aber in einigen Fällen haben wir sie als notwendig erachtet.

Da der Client nun die SQLException abfängt, kann er sich den von SQL Server in der Exception zurückgegebenen Fehlercode ansehen und dann (falls erforderlich) spezielle Maßnahmen ergreifen, wenn die Exception abgefangen wird und die Fehlernummer einen bestimmten Wert hat. Dies ermöglicht eine zweite Ebene der Fehlerbehandlung auf der Grundlage des Fehlercodes, wenn dies für die benutzerdefinierten Fehler (>50000) erforderlich ist.

Dies ermöglicht es den DBAs auch, benutzerdefinierte Fehler zu erzeugen und dem Client-Code eine konsistente Möglichkeit zu geben, diese zu behandeln. Die DBAs müssten dann den Client-Code-Affen über die benutzerdefinierten Fehler informieren, damit sie sich darauf vorbereiten können.

Normalerweise verwende ich die Rückgabecodes nicht für die Fehlerbehandlung, obwohl ich sehe, wie sie verwendet werden könnten, aber das bedeutet mehr Logik in der Code-Affenschicht, um den Rückgabecode zu betrachten und zu behandeln. Wenn es ein Problem gibt, möchte ich, dass eine Ausnahme zurückgegeben wird, weil ich dann konsequent damit umgehen kann. Wenn ich mir auch die Rückgabecodes ansehen muss, gibt es jetzt mehrere Möglichkeiten der Fehlerbehandlung.

2voto

Jeff Olson Punkte 329

Ich verwende in der Regel einen Ausgabeparameter - und definiere die möglichen Werte.

0 = Erfolg
Postive Ganzzahl (z. B. bei einer Einfügung) = Neue Zeilenkennung (@@identity)

Negative Ganzzahl = Bekannte mögliche Fehlerbedingungen
-1 = Fehlender @Nachname (oder Länge Null)
-2 = Fehlender @Vorname (oder Länge Null)
...usw...

Dies wird etwas mühsam zu definieren sein - aber es ist erweiterbar - und es ist ein Weg, um sinnvolle Ergebnisse zurück an Ihre Kunden zu bekommen und für eine Datenzugriffsschicht, um einen genauen Grund für einen Fehler an eine Geschäftsobjektschicht zurückzugeben (ich verwende Enums in der Geschäftsobjektschicht für verschiedene Statusbedingungen).

Es ist auch möglich, dass eine Datenzugriffsschicht Ausnahmen auslöst, wenn dies gewünscht wird - aber ich glaube, dass es aus Kostengründen und aus Sicht der Leistung besser ist, keine Fehler auszulösen, wenn man einfach einen Enum- oder Integer-Wert überprüfen kann.

Es gibt noch andere Techniken - dies ist nur eine, die ich in der Vergangenheit mit einigem Erfolg angewendet habe.

2voto

KM. Punkte 98297

Hier ist meine Empfehlung:

0 zurückgeben, wenn alles in Ordnung ist
bei einem logischen Fehler, fehlenden oder ungültigen Daten ein negatives x zurückgeben
ein positives x zurückgeben, wenn ein schwerwiegender Fehler auftritt, ein Fehler beim Einfügen, usw.

Hinzufügen der Ausgabeparameter ErrorMsg und ErrorLog zu den gespeicherten Prozeduren. ErrorMessage enthält eine von Menschen lesbare Meldung, ErrorLog enthält Debug-Informationen.
Diese werden NULL sein, wenn 0 zurückgegeben wird.
Sie können ErrorLog verwenden, um alle Probleme aufzuzeichnen. Wenn Sie sie in eine Tabelle einfügen, sollten Sie dies nach dem Rollback tun.

Verwenden Sie TRY - Catch, um Probleme zu erfassen, und erstellen Sie Ihre eigene Nachricht, und geben Sie die Informationen unter Verwendung der oben genannten Konventionen zurück.

2voto

DaveE Punkte 3559

Bei meiner derzeitigen Arbeitsstelle sind Ausnahmen vorgesehen für außergewöhnlich Bedingungen. Für Dinge wie fehlerhafte Parameter oder ähnliches haben wir Standard-Rückgabecodes - ungültige Parameterwerte geben zum Beispiel immer 98 zurück. (Warum 98? Das ist für die Geschichte verloren...)

Dies ist nicht unbedingt ideal, da sowohl der Kunde als auch der SP verstehen müssen, was ein bestimmter Rückgabecode bedeutet; es ist eine schlechte Trennung der Anliegen.

In besonderen Fällen verwenden wir OUT-Parameter, um Nachrichten zurückzugeben, und unsere Batch-Dienste verwenden eine standardisierte #scratch-Tabelle.

Bei einem früheren Arbeitgeber haben wir für dieselben Zwecke benutzerdefinierte SQL-Fehler verwendet. Verwenden Sie also, was sinnvoll ist. Ich persönlich bevorzuge einen einzigen Mechanismus, aber das ist je nach Ihrer Umgebung vielleicht nicht möglich.

Vielleicht sollten Sie sich alle zusammentun, um standardisierte Verfahren für den Client-Code zu entwickeln. Die in Excel verwendete VBA hat deutliche Einschränkungen, die der C#- und Java-Code nicht hat, und so ähnlich sich Java und C# auch sind, sie sind nicht identisch. Wenn Sie bei der Rückgabe von Ausnahmen bleiben wollen Wenn man sich dann auf a) einen bekannten Bereich von Meldungen, die "Fehler"-Ausnahmen anzeigen, und b) ein standardisiertes Meldungslayout einigen kann, so dass ein standardisiertes Parsing stattfinden kann, sind die Entwickler zu 90 % fertig.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X