Detaillierte Erläuterung von Beispielen zur Fehlerbehandlung in gespeicherten MySQL-Prozeduren

Detaillierte Erläuterung von Beispielen zur Fehlerbehandlung in gespeicherten MySQL-Prozeduren

Dieser Artikel beschreibt anhand eines Beispiels die Fehlerbehandlung von MySQL Stored Procedures. Teilen Sie uns die Einzelheiten zu Ihrer Information mit:

Wenn in einer gespeicherten Prozedur ein Fehler auftritt, ist es wichtig, diesen entsprechend zu behandeln, zum Beispiel: die Ausführung des aktuellen Codeblocks fortzusetzen oder zu beenden und eine aussagekräftige Fehlermeldung auszugeben. MySQL bietet eine einfache Möglichkeit, Handler zu definieren, die verschiedene Bedingungen verarbeiten, von allgemeinen Bedingungen wie Warnungen oder Ausnahmen bis hin zu spezifischen Bedingungen wie bestimmten Fehlercodes. Versuchen wir nun, mit der Anweisung DECLARE HANDLER einen Handler zu deklarieren. Sehen wir uns zunächst die Syntax an:

DECLARE-Aktion HANDLER FÜR Condition_Value-Anweisung;

Wenn im obigen SQL der Wert der Bedingung mit condition_value übereinstimmt, führt MySQL die Anweisung aus und setzt den aktuellen Codeblock je nach Operation fort oder beendet ihn. Dabei akzeptiert „action“ einen der folgenden Werte:

  • CONTINUE: Setzt die Ausführung des umschließenden Codeblocks fort (BEGIN ... END).
  • EXIT: Der Handler erklärt die Beendigung der Ausführung des eingeschlossenen Codeblocks.

condition_value gibt eine bestimmte Bedingung oder eine Klasse von Bedingungen an, die den Handler aktivieren. condition_value akzeptiert einen der folgenden Werte:

  • Ein MySQL-Fehlercode.
  • Ein Standard-SQLSTATE-Wert oder eine SQLWARNING-, NOTFOUND- oder SQLEXCEPTION-Bedingung, die eine Abkürzung für eine Klasse von SQLSTATE-Werten ist. Die Bedingung NOTFOUND wird mit einem Cursor oder einer SELECT INTO variable_list-Anweisung verwendet.
  • Eine benannte Bedingung, die mit einem MySQL-Fehlercode oder SQLSTATE-Wert verknüpft ist.

Am wichtigsten ist, dass das obige SQL eine einfache Anweisung oder eine zusammengesetzte Anweisung sein kann, die von den Schlüsselwörtern BEGIN und END umgeben ist. Nachdem wir das nun hinter uns gebracht haben, schauen wir uns ein paar Beispiele für die Deklaration von Handlern an. Wenn im Programm zunächst ein Fehler auftritt, wird der Wert der Variable has_error auf 1 gesetzt und die Ausführung fortgesetzt:

DECLARE CONTINUE HANDLER FÜR SQLEXCEPTION SET has_error = 1;

Sehen wir uns nun an, was passiert, wenn ein Fehler auftritt. Dann wird der vorherige Vorgang rückgängig gemacht, eine Fehlermeldung ausgegeben und der aktuelle Codeblock verlassen. Wenn Sie es innerhalb des BEGIN END-Blocks einer gespeicherten Prozedur deklarieren, beendet es die gespeicherte Prozedur sofort:

DECLARE EXIT HANDLER FÜR SQLEXCEPTION
BEGINNEN
ROLLBACK;
SELECT 'Ein Fehler ist aufgetreten, der Vorgang wurde zurückgesetzt und die gespeicherte Prozedur wurde beendet';
ENDE;

Der folgende Handler bedeutet, dass, wenn im Falle eines Cursors oder einer „Select into“-Anweisung keine weiteren Zeilen zum Abrufen vorhanden sind, der Wert der Variable „no_row_found“ auf 1 gesetzt und die Ausführung fortgesetzt wird:

DECLARE CONTINUE HANDLER FÜR NICHT GEFUNDEN SET no_row_found = 1;

Der folgende Handler gibt den MySQL-Fehler 1062 aus, wenn ein Fehler aufgrund eines doppelten Schlüssels auftritt. Es gibt eine Fehlermeldung aus und setzt die Ausführung fort:

DECLARE CONTINUE HANDLER FÜR 1062
SELECT 'Fehler, doppelter Schlüssel aufgetreten';

Die obigen Beispiele sind möglicherweise etwas abstrakt. Erstellen wir daher eine neue Tabelle mit dem Namen „article_tags“ und gehen wie folgt vor:

VERWENDEN Sie testdb;
Tabelle erstellen Artikel-Tags(
  Artikel-ID INT,
  tag_id INT,
  PRIMÄRSCHLÜSSEL (Artikel-ID, Tag-ID)
);

Darunter speichert die Tabelle „article_tags“ die Beziehung zwischen Artikeln und Tags. Jeder Artikel kann viele Tags haben und umgekehrt. Der Einfachheit halber erstellen wir weder die Artikel- und Tag-Tabellen noch die Fremdschlüssel in der Tabelle „article_tags“.

Zum Abschluss erstellen wir eine gespeicherte Prozedur, um die Artikel-ID und die Tag-ID in die Tabelle „article_tags“ einzufügen:

VERWENDEN Sie testdb;
TRENNUNGSZEICHEN $$
VERFAHREN ERSTELLEN insert_article_tags(IN article_id INT, IN tag_id INT)
BEGINNEN
 DECLARE CONTINUE HANDLER FÜR 1062
 SELECT CONCAT('doppelte Schlüssel (',article_id,',',tag_id,') gefunden') AS msg;
 -- einen neuen Datensatz in article_tags einfügen
 INSERT INTO Artikel-Tags(Artikel-ID, Tag-ID)
 WERTE(Artikel-ID, Tag-ID);
 -- Tag-Anzahl für den Artikel zurückgeben
 Wählen Sie COUNT(*) aus Artikel-Tags;
ENDE$$
TRENNUNGSZEICHEN ;

Anschließend fügen wir der Artikel-ID 1 die Tag-IDs 1, 2 und 3 hinzu, indem wir die gespeicherte Prozedur insert_article_tags aufrufen, wie unten gezeigt:

Rufen Sie insert_article_tags(1,1) auf;
Rufen Sie insert_article_tags(1,2) auf;
Rufen Sie insert_article_tags(1,3) auf;

Versuchen wir, einen doppelten Schlüssel einzufügen, um zu überprüfen, ob der Handler tatsächlich aufgerufen wird:

Rufen Sie insert_article_tags(1,3) auf;

Führen Sie die obige Abfrageanweisung aus und erhalten Sie die folgenden Ergebnisse:

mysql> CALL insert_article_tags(1,3);
+----------------------------+
| Nachricht |
+----------------------------+
| doppelte Schlüssel (1,3) gefunden |
+----------------------------+
1 Reihe im Set
+----------+
| ANZAHL(*) |
+----------+
| 3 |
+----------+
1 Reihe im Set
Abfrage OK, 0 Zeilen betroffen

Nach der Ausführung erhalten Sie eine Fehlermeldung. Da wir den Handler jedoch als CONTINUE-Handler deklariert haben, wird die gespeicherte Prozedur weiterhin ausgeführt. Daher beträgt der endgültige Tag-Anzahlwert des Artikels: 3. Schauen wir uns ein Bild an:

Wenn Sie jedoch CONTINUE in der Handler-Deklaration in EXIT ändern, erhalten Sie nur eine Fehlermeldung. Die folgende Abfrageanweisung:

TRENNUNGSZEICHEN $$
VERFAHREN ERSTELLEN insert_article_tags_exit(IN article_id INT, IN tag_id INT)
BEGINNEN
 DECLARE EXIT HANDLER FÜR SQLEXCEPTION 
 SELECT 'SQLException aufgerufen';
 DECLARE EXIT HANDLER FÜR 1062 
    SELECT 'MySQL-Fehlercode 1062 aufgerufen';
 DECLARE EXIT HANDLER FÜR SQLSTATE '23000'
 SELECT 'SQLSTATE 23000 aufgerufen';
 -- einen neuen Datensatz in article_tags einfügen
 INSERT INTO Artikel-Tags(Artikel-ID, Tag-ID)
  WERTE(Artikel-ID, Tag-ID);
 -- Tag-Anzahl für den Artikel zurückgeben
 Wählen Sie COUNT(*) aus Artikel-Tags;
ENDE $$
TRENNUNGSZEICHEN ;

Führen Sie die obige Abfrageanweisung aus und erhalten Sie die folgenden Ergebnisse:

mysql> CALL insert_article_tags_exit(1,3);
+-------------------------------+
| MySQL-Fehlercode 1062 aufgerufen |
+-------------------------------+
| MySQL-Fehlercode 1062 aufgerufen |
+-------------------------------+
1 Reihe im Set
Abfrage OK, 0 Zeilen betroffen

Schauen wir uns ein Bild an:

Wenn wir mehr als einen Handler zur Behandlung eines Fehlers verwenden, ruft MySQL den spezifischsten Handler zur Behandlung des Fehlers auf. Dabei geht es um die Frage der Priorität. Schauen wir uns das genauer an.

Wir wissen, dass Fehler immer einem MySQL-Fehlercode zugeordnet werden, da dieser in MySQL am spezifischsten ist. SQLSTATE kann vielen MySQL-Fehlercodes zugeordnet werden und ist daher nicht zu spezifisch. SQLEXCPETION oder SQLWARNING ist eine Abkürzung für den Typwert SQLSTATES und daher am allgemeinsten. Angenommen, in der gespeicherten Prozedur insert_article_tags_3 sind drei Handler wie folgt deklariert:

TRENNUNGSZEICHEN $$
VERFAHREN ERSTELLEN insert_article_tags_3(IN article_id INT, IN tag_id INT)
BEGINNEN
 DECLARE EXIT HANDLER FOR 1062 SELECT 'Fehler wegen doppelter Schlüssel aufgetreten';
 DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT 'SQLException aufgetreten';
 DECLARE EXIT HANDLER FÜR SQLSTATE '23000' SELECT 'SQLSTATE 23000';
 -- einen neuen Datensatz in article_tags einfügen
 INSERT INTO Artikel-Tags(Artikel-ID, Tag-ID)
 WERTE(Artikel-ID, Tag-ID);
 -- Tag-Anzahl für den Artikel zurückgeben
 Wählen Sie COUNT(*) aus Artikel-Tags;
ENDE $$
TRENNUNGSZEICHEN ;

Anschließend versuchen wir, den doppelten Schlüssel in die Tabelle article_tags einzufügen, indem wir eine gespeicherte Prozedur aufrufen:

Rufen Sie insert_article_tags_3(1,3) auf;

Wie unten gezeigt, können Sie sehen, dass der MySQL-Fehlercode-Handler aufgerufen wird:

mysql> CALL insert_article_tags_3(1,3);
+----------------------------------+
| Fehler wegen doppelter Schlüssel aufgetreten |
+----------------------------------+
| Fehler wegen doppelter Schlüssel aufgetreten |
+----------------------------------+
1 Reihe im Set
Abfrage OK, 0 Zeilen betroffen

Nachdem wir nun fertig sind, schauen wir uns die Verwendung benannter Fehlerbedingungen an. Beginnen Sie mit der Deklaration des Fehlerhandlers wie folgt:

DECLARE EXIT HANDLER FOR 1051 SELECT 'Bitte erstellen Sie zuerst die Tabelle abc';
WÄHLEN SIE * VON abc;

Was bedeutet die Zahl 1051? Stellen Sie sich vor, Sie haben einen umfangreichen gespeicherten Prozedurcode, der viele Zahlen wie diese verwendet. Die Wartung des Codes wird zu einem Albtraum. Glücklicherweise stellt MySQL uns die Anweisung DECLARE CONDITION zur Verfügung, um einen benannten Fehlerzustand zu deklarieren, der mit einer Bedingung verknüpft ist. Die Syntax der Anweisung DECLARE CONDITION lautet wie folgt:

DECLARE Bedingungsname BEDINGUNG FÜR Bedingungswert;

condition_value kann ein MySQL-Fehlercode, beispielsweise 1015, oder ein SQLSTATE-Wert sein. Der Bedingungswert wird durch den Bedingungsnamen dargestellt. Nach der Deklaration können Sie sich auf den Bedingungsnamen statt auf den Bedingungswert beziehen. Der obige Code kann also wie folgt umgeschrieben werden:

DECLARE table_not_found BEDINGUNG für 1051;
DECLARE EXIT HANDLER FOR table_not_found SELECT 'Bitte erstellen Sie zuerst die Tabelle abc';
WÄHLEN SIE * VON abc;

Dieser Code ist offensichtlich besser lesbar als der vorherige Code, wir sollten jedoch beachten, dass die Bedingungsdeklaration vor der Handler- oder Cursordeklaration erscheinen muss.

Okay, das ist alles für dieses Mal.

Leser, die an weiteren MySQL-bezogenen Inhalten interessiert sind, können sich die folgenden Themen auf dieser Site ansehen: „Kenntnisse zu gespeicherten MySQL-Prozeduren“, „Zusammenfassung der allgemeinen MySQL-Funktionen“, „Kenntnisse zu MySQL-Protokollvorgängen“, „Zusammenfassung der Kenntnisse zu MySQL-Transaktionsvorgängen“ und „Zusammenfassung der Kenntnisse zu MySQL-Datenbanksperren“.

Ich hoffe, dass dieser Artikel für jedermann beim Entwurf einer MySQL-Datenbank hilfreich ist.

Das könnte Sie auch interessieren:
  • Zusammenfassung der if- und case-Anweisungen in MySQL
  • Detaillierte Erklärung des Prinzips und der Verwendung des Cursors (DECLARE) in der gespeicherten MySQL-Prozedur
  • Beispiel für eine gespeicherte MySQL-Prozedurmethode zum Zurückgeben mehrerer Werte
  • So erstellen (CREATE PROCEDURE) und rufen (CALL) Sie eine gespeicherte MySQL-Prozedur auf und so erstellen (DECLARE) und weisen (SET) Sie eine Variable zu
  • Beispielanalyse von gespeicherten MySQL-Prozeduren, die Fehlerbedingungen in gespeicherten Prozeduren auslösen (SIGNAL- und RESIGNAL-Anweisungen)
  • Detaillierte Erläuterung der Prinzipien und der Verwendung von gespeicherten MySQL-Prozeduren
  • Definition und Zuweisung von Variablen in gespeicherten MySQL-Prozeduren
  • Einführung in die Verwendung der Cursorschleife für gespeicherte Prozeduren in MySQL
  • Beispiel für eine gespeicherte MySQL-Prozedur (einschließlich Transaktionen, Ausgabeparameter, verschachtelte Aufrufe)
  • Detaillierte Erläuterung der gespeicherten Prozeduren und Funktionen von MySql
  • Detailliertes Beispiel für die Verwendung der if-Anweisung in einer gespeicherten MySQL-Prozedur

<<:  Vue implementiert einen einfachen Lupeneffekt

>>:  VSCode-Entwicklung UNI-APP Konfigurations-Tutorial und Plugin

Artikel empfehlen

Nginx definiert die Zugriffsmethode für Domänennamen

Ich erstelle derzeit Nginx, kann aber nicht über ...

JS realisiert die Kartenausgabe-Animation

In diesem Artikelbeispiel wird der spezifische JS...

Einführung in Fork in Multithreading unter Linux

Inhaltsverzeichnis Frage: Fall (1) Fork vor dem E...

Detaillierte grundlegende Operationen an Datentabellen in der MySQL-Datenbank

Inhaltsverzeichnis 1. Zeigen Sie die Tabellen in ...

MySQL-Einschränkungstypen und Beispiele

Zwang Einschränkungen gewährleisten Datenintegrit...

jQuery implementiert einen einfachen Kommentarbereich

In diesem Artikel wird der spezifische Code von j...

So führen Sie ein Projekt mit Docker aus

1. Geben Sie das Verzeichnis ein, in dem Ihr Proj...

Häufige Browserkompatibilitätsprobleme (Zusammenfassung)

Browserkompatibilität ist nichts anderes als Stil...

js implementiert dynamisch Operationen zum Hinzufügen und Löschen von Tabellen

In diesem Artikelbeispiel wird der spezifische Co...

So passen Sie mit CSS einen schöneren Link-Prompt-Effekt an

Vorschlag: Das möglichst häufige handschriftliche ...