Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

SQL Server 2016: Triggers, Stored Procedures und Funktionen

Fehlerbehandlung

Testen Sie unsere 2021 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Mittels TRY ... CATCH und einer Reihe von Funktionen kann auch mit T-SQL Fehlerbehandlung programmiert werden.
10:20

Transkript

Die Entwicklung mit Soterd Proceduren ermöglicht auch die Verwendung von Fehlerbehandlung in Form von Try/Catch. Das heißt, Sie können, bekannt vielleicht aus der Entwicklung mit Java, oder C Sharp oder VB.NET entsprechend Bereiche definieren in einem Tryblock. Wenn in diesem Tryblock einen Feheler auftritt, dann wird die Ausführung weitergeführt an der ersten Zeile des Catchs-Blocks. Dort haben Sie die Möglichkeit, einen Fehler zu behandeln, und in der Regel wird so aussehen, dass Sie den Fehler entweder ignorieren vielleicht nicht so gut, soll man darüber nachdenken, ob es eine gute Lösung ist, oder den Fehler protokollieren, und wenn Sie möchten den Fehler weiter in den Aufrufer nach oben zu reichen. Wenn Sie möchten, können Sie auch eigene Fehler erzeugen, es muss kein natürlicher Fehler sein, weil möglicherweise etwas mit den Parametern oder der Ausgangssituation, in der Stored Procedure aufgerufen wird, nicht stimmt. Sie können mit RAISEERROR oder THROW, ab SQS-Server 2012, entsprechend Fehler auch künstlich erzeugen. Egal wie Sie es machen, Sie haben immer eine Reihe von Funktionen zu Hand, die Sie benutzen können, um rauszufinden, was in der Tat wirklich das Problem war, Sie können also den Fehlercode abfragen, Sie können den Schweregrad abfragen, den Status eines Fehlers können Sie abfragen. Das bedeutet, wenn Sie eine Fehlersituation haben, kann es sein, dass es aus gewissen unterschiedlichen Unterstatus- Werten quasi resultiert, wenn Sie sich überlegen, könnte es sein, das Löschen einer Tabelle kann nicht funktionieren, weil beispielsweise die Tabelle keine Zeilen hat, das könnte eine Fehler-Kondition für Sie sein mit Status 1 oder das Löschen funktioniert nicht aus irgendwelche technischen Gründen, dann es ist der gleiche Fehler für Sie, aber Sie haben entsprechend ein Status 2 oder ähnliches. Das heißt, da kann man differenzieren, ohne dass man zu viele Fehlercodes erzeugen muss. Dann können Sie abfragen, in welcher Prozedur oder Triggern entsprechend das Problem aufgetreten ist. Das funktioniert natürlich nur, wenn Sie wirklich auch innerhalb einer Prozedur oder eines Triggers sind, wenn Sie in der Batchverarbeitung sind des SQL-Serves, ist der Wert leer. Dann können Sie ausgeben, in welche Zeile entsprechend der Fehler aufgetreten ist, das geht auch, und natürlich last but not least, die Fehlermeldung selber entsprechend, damit Sie wissen, was das Problem ist und was Sie laugen sollen. In SQL-Server allerdings ist, dass die Fehlermeldungen meistens nicht so geeignet sind, dass sie wirklich an den Anwender weitergereicht werden können, sondern sehr technisch sind, aber sich durchaus sehr gut eignen um protokoliert zu werden, damit Sie später den Fehler nachvollziehen und beheben können. In der Praxis sieht das Ganze dann so aus, ich lege zunächst eine Datenbank für das kleine Demo an, dann habe ich hier eine Stored Procedure, die nichts weiter macht als die sechs Funktionen für die Fehler, die Sie gerade gesehen haben, einfach auszugeben, über ein SELECT-Statement, und eine Stored Procedure, die aus unterschiedlichen Gründen, Fehler auslösen kann. Wesentlich sehen Sie hier ein BEGIN TRY, END TRY, BEGIN CATCH, END CATCH. Es gibt kein Konstrukt, kein Gedanke für ein FINALLY oder Ähnliches. Das heißt, was in diesem Block hier geschieht, wenn dies zum Fehler führt, wird die Ausführung hier im CATCH-Block fortgeführt. Hier mache ich eigentlich etwas, was nicht notwendig ist, aber ich möchte es in diesem Demo zeigen, und zwar benutze ich die globale Variable @@ERROR und die liefert mir den Fehlercode, der letzten Anweisung, bzw. wenn es kein Fehler gibt, schlicht 0, und hier kann ich quasi testen, ob es wirklich ein Fehler gegeben hat. Da ich aber im CATCH-Block bin, erübrigt sich das eigentlich, aber wie gesagt, ich möchte es in diesem Demo auch zeigen. Dann wird die Stored Procedure aufgerufen, die die Ausgabe der Fehlerdetails übernimmt, und zum Schluss rufe ich die Stored Procedure hier selber auf, mit der ich die einzelnen Fehler auflösen möchte. Zunächst einmal RAISERROR, hier habe ich die größte Möglichkeit gewisse Parameter anzugeben. Ich kann sagen, welchen Fehlertext ich haben möchte, ich kann den Schwierigskeitsgrad festlegen, wobei Fehler sollten entsprechend zwischen 11 und 19, je höher, desto schwieriger, oder schwerwiegender entsprechend deklariert werden, und dann kann ich ein State oder ein Status festlegen, und ich kann darüber hinaus noch optional mit WITH einige zusätzliche Angabe machen. Zum Beispiel kann ich mit LOG festlegen, dass dieser Fehler in das Serverlog geschrieben werden soll. Ich kann mit NOWAIT festlegen, dass der Fehler sofort an den Client geschickt wird, sonst kann es sein, dass es gekascht wird, je nachdem, wie schwer der Fehler ist. Und mir SETARROW kann ich sicherstellen, dass das definitiv als Fehler behandelt wird, egal was sich hier oben als Schweregrad angegeben habe, also selbst wenn ich nur 1 bis 10 verwende, was eigentlich für Info steht, kann ich daraus explizit einen Fehler machen. So wenn ich das jetzt ausführe, dann bekomme ich als Ausgabe das: die Fehlernummer 50000, ich habe keine spezielle angegeben, deshalb nimmt RAISERROR automatisch 50000, aber Sie sehen hier den Schwergrad, den State, die Stored Procedure, die das Problem verursacht hat, leider ohne Schema, aber zumindest haben wir das Stored Procedure vorhanden, dann die Fehlerzeile und den tatsächlichen Text. Weil ich hier LOG angegeben habe, kann ich zum Beispiel hier einmal unter Management, unter Serverlogs ins aktuellen Servelog und Sie sehen hier RAISERROR löst einen Fehler aus, inklusive den Fehler 50000 Schweregrad 11, also den weiteren Metainformation, das heißt, diese beiden Anträge resultieren aus der Tatsache, dass ich hier oben LOG angegeben habe. Dann kann ich die Stored Procedure umbauen. Ich kann quasi hingehen und das auskommentieren. Dafür entsprechend den künstlichen Fehler mit THROW auslösen: Da gebe ich am 50001, das ist der Fehlercode, dann den Text und den State, den ich habe möchte, und ich kann es ganz normal laufen lassen. Sie erinnern sich, die Datenbank wird neu angelegt, und so ist es kein Problem, ich sehe jetzt hier das THROW diesen Fehler ausgelöst hat. THROW hat den Vorteil, dass es ein bisschen kompakter ist und mit THROW habe ich auch die Möglichkeit Fehlercodes anzugeben, die nicht vorher registrieren muss. Wenn ich bei RAISERROR explizit einen Fehlercode eingebe, muss der entsprechend instanzweit registriert sein, das ist ein bisschen unhandlich und in vielen Fällen einfach ein bisschen überdimensioniert. Und ich natürlich wirklich auf einen echten Fehler stoßen, weil ich zum Beispiel vergessen habe, dass man nicht durch 0 teilen kann, und dann bekomme ich entsprechend diese Ausgabe, das ist der echter Fehlercode, der für Division durch 0 steht,, Schweregrad Grad 16, also schon mal gar nicht so ohne, ErroState 1, es ist die gleiche Stored Procedure natürlich, in Zeile 8 und entsprechend das ist der Meldungstext. Zeile 8 wird Ihnen wahrscheinlich auffallen, dass das möglicherweise nicht genau Ihre Erwartung ist, das ist sicherlich nicht Zeile 8, ich könnte natürlich mal anfangen zu zählen und sagen 1, 2, 3, 4, 5, 6, 7, 8. Das bedeutet, acht seit dem letzten GO. Wenn ich also hier quasi eine Zeile einfüge, habe ich hier entsprechend eine 9 stehen. Also das ist ein bisschen unangenehm. Man würde wahrscheinlich erwarten, dass er hier in der Zeile den Fehler findet, das heißt, es könnte vielleicht seit dem Beginn möglicherweise gezählt sein, nein, es ist seit dem letzten GO und wenn ich Zeilen einfüge, steigt den Fehlernummern. Das macht die Sache ein wenig unhandlich gerade bei komplexeren Stored Proceduren, da wirklich die Stelle zu finden, wo der Fehler entsprechend aufgetreten ist. Nichtsdestotrotz ich kann bei komplexeren Stored Proceduren die Strategie anwenden, dass ich einzelnen Funktionalitäten in einzelnen Stored Proceduren unterbringe, das könnte helfen, und ich kann natürlich auch mehrere TRY CATCH-Blöcke anlegen, sodass ich eine grobe Idee habe, wo das ganze Problem aufgetreten ist, und mich nicht so sehr auf die Zeile, in der den Fehler aufgetreten ist, verlassen muss. Was ich jetzt machen kann, ich kann den Fehler entsprechend auch eigentlich nach oben weiterleiten, wenn ich das möchte, weil Sie sehen hier, die Ausführung sagt mir, dass es keinen Fehler gekommen ist, genau deswegen, weil einen entsprechenden CATCH-Block habe und ich könnte zum Beispiel auch den Fehler einfach mit THROW jetzt hier ohne weitere Parameter nach oben reichen, wenn ich zum Beispiel in den CATCH-Block festgestellt habe, dass der Fehler für mich doch nicht in irgendeiner Form reparable ist, oder dass ich mich nur auf das Loggen konzentrieren möchte, aber den Fehler trotzdem nach oben weiterreichen möchte oder muss. Das heißt, wenn ich das laufen lasse, sieht das entsprechend so aus, dass ich auch hier dann in der Tat die echte Fehlermeldung bekomme, und die geht jetzt an den Client, in den Fall in SQL Server Management Studio, wenn Sie mit ADO.NET oder ODBC entwickeln, werden Sie entsprechend genau die gleiche Situation vorfinden, der Fehler wird jetzt hier an den Client weitergereicht. Damit haben Sie gesehen, wie Sie Fehler auslösen können, braucht man gewissen Situationen. Sie haben gesehen, wie man entsprechend Fehler abfangen kann mit TRY CATCH und wenn Sie möchten sogar den Fehler nach oben reichen oder wenn Sie es einfach weglassen, das war die Ursprungssituation, dann wird der Fehler als behandelt angesehen und entsprechend nicht weiterverfolgt. Ansonsten würde der Aufrufer der Stored Procedure diesen Fehler bekommen, das könnte eine andere Stored Procedure sein, da kann eine richtige Verkettung stattfinden. Und wenn alle den Fahler nach oben reichen, bekommt der Client, spricht der letzte Aufrufer, der die Stored Procedure oder die Kette des Stored Procedures ausgelöst hat, den Fehler letztendlich zu sehen.

SQL Server 2016: Triggers, Stored Procedures und Funktionen

Nutzen Sie in SQL Server Trigger, gespeicherte Prozeduren, Late Binding, Fehlerbehandlung sowie Scalar- und Tabellenwertfunktionen.

3 Std. 12 min (44 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Hersteller:
Software:
Exklusiv für Abo-Kunden
Erscheinungsdatum:08.08.2016

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!