Ich bin nicht sehr vertraut mit MYSQL-Funktionen und Ausnahmebehandlung. Nach all den Recherchen konnte ich mir unten etwas einfallen lassen, aber ohne Gewinn.

Ich versuche, 0 zurückzugeben, wenn die Ausführung der Einfügeanweisung fehlschlägt, und andernfalls 1. Die Ausnahme wird ausgelöst, anstatt behandelt zu werden. Wo gehe ich falsch?


    CREATE DEFINER=`myusr`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int(1)
        READS SQL DATA
        DETERMINISTIC
    BEGIN
        DECLARE EXP DATETIME;
        DECLARE RINT INT(1);
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
        BEGIN
           RETURN  0;
        END;
        SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
        INSERT INTO `mydb`.`my_tbl`
            (`C1`,
            `C2`,
            `C3`)
            VALUES
            (p1, p2, exp);
        SET RINT = 1;
        RETURN RINT;
    END

TABELLE - my_tbl

enter image description here

ERFOLGSFALL - func1 ('ABC', '123456')

enter image description here

AUSNAHMEFALL - func1 ('ABC', '123456789')

enter image description here

BEARBEITEN - Screenshots hinzugefügt

0
Snehasis Panda 22 Feb. 2020 im 12:55

3 Antworten

Beste Antwort

Es scheint, dass MySQL 8.0.19 nicht alle Fehler abfangen und richtig behandeln kann.

Fehlercode: 1406. Daten zu lang für Spalte 'p2' in Zeile 1

Fehlercode: 1049. Unbekannte Datenbank 'mydb'

Sind zwei Beispiele, die ich getestet habe und die nicht funktioniert haben, andere tun dies, ich denke, dies ist eher ein Fall für das MySQL-Forum.

DELIMITER $$
CREATE DEFINER=`mydb`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int
    READS SQL DATA
    DETERMINISTIC
BEGIN
    DECLARE EXP DATETIME;
    DECLARE RINT INT(1);
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIn
       RETURN  0;
    END;
    SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
    INSERT INTO `mydb`.`func1`
        (`C1`,
        `C2`,
        `C3`)
        VALUES
        (p1, p2, exp);
    SET RINT = 1;
    RETURN RINT;
END;
DE§LIMITER ;

Dieses Szenario funktioniert. Ich habe für die referenzierte Variable p2 die Größe erhöht, um sie an die eingegebenen Daten anzupassen, und ich habe einen Exit-Handler für den Fehler 1265 hinzugefügt. Dies ist der Fehler, den Sie erhalten, wenn Sie versuchen, den Langtext einzufügen.

Fehlercode: 1265. Daten für Spalte 'c2' in Zeile 1 abgeschnitten

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(20)) RETURNS int
    MODIFIES SQL DATA
    DETERMINISTIC
BEGIN
    DECLARE EXP DATETIME;
    DECLARE RINT INT(1);
    BEGIN
    DECLARE EXIT HANDLER FOR 1265 RETURN 0;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN 0;


    SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
    INSERT INTO `mydb`.`my_tbl`
        (`C1`,
        `C2`,
        `C3`)
        VALUES
        (p1, p2, exp);
        SET RINT = 1;
        RETURN RINT;
    END;    
END$$
DELIMITER ;

Der Fehler, den Sie erhalten haben, liefert die Fehlermeldung, bevor Sie einen HANDLER hinzufügen

1
nbk 22 Feb. 2020 im 21:07

Die Rolle der TRY-Anweisung besteht darin, die Ausnahme zu erfassen. (Da dieser Prozess normalerweise mehrere Anweisungen umfasst, wird normalerweise der Begriff "TRY-Block" anstelle von "TRY-Anweisung" verwendet.) Wenn innerhalb des TRY-Blocks eine Ausnahme auftritt, liefert der Teil des Systems, der als Ausnahmebehandler bezeichnet wird, die Ausnahme an den anderen Teil des Programms, der die Ausnahme behandelt. Dieser Programmteil wird mit dem Schlüsselwort CATCH bezeichnet und daher als CATCH-Block bezeichnet.

HINWEIS

Die Ausnahmebehandlung mit den Anweisungen TRY und CATCH ist die übliche Methode, mit der moderne Programmiersprachen wie C # und Java Fehler behandeln.

Die Ausnahmebehandlung mit den Blöcken TRY und CATCH bietet einem Programmierer viele Vorteile, wie z.

Exceptions provide a clean way to check for errors without cluttering code
Exceptions provide a mechanism to signal errors directly rather than using some side effects
Exceptions can be seen by the programmer and checked during the compilation process

SQL Server 2012 führt die dritte Anweisung in Bezug auf die Behandlung von Fehlern ein: THROW. Mit dieser Anweisung können Sie eine Ausnahme auslösen, die im Ausnahmebehandlungsblock abgefangen wurde. Einfach ausgedrückt ist die THROW-Anweisung ein weiterer Rückgabemechanismus, der sich ähnlich wie die bereits beschriebene RAISEERROR-Anweisung verhält.

Beispiel 1 zeigt, wie die Ausnahmebehandlung mit TRY / CATCH / THROW funktioniert. Es wird gezeigt, wie Sie die Ausnahmebehandlung verwenden können, um alle Anweisungen in einen Stapel einzufügen oder die gesamte Anweisungsgruppe zurückzusetzen, wenn ein Fehler auftritt. Das Beispiel basiert auf der referenziellen Integrität zwischen den Abteilungs- und Mitarbeitertabellen. Aus diesem Grund müssen Sie beide Tabellen mit den Einschränkungen PRIMARY KEY und FOREIGN KEY erstellen.

BEISPIEL 1

0270_001

Nach der Ausführung des Stapels in Beispiel 1 werden alle drei Anweisungen im Stapel überhaupt nicht ausgeführt. Die Ausgabe dieses Beispiels lautet:

0271_001

Die Ausführung von Beispiel 1 funktioniert wie folgt. Die erste INSERT-Anweisung wird erfolgreich ausgeführt. Dann verursacht die zweite Anweisung den referenziellen Integritätsfehler. Da alle drei Anweisungen in den TRY-Block geschrieben sind, wird die Ausnahme "ausgelöst" und der Ausnahmebehandler startet den CATCH-Block. CATCH setzt alle Anweisungen zurück und druckt die entsprechende Nachricht. Danach gibt die THROW-Anweisung die Ausführung des Stapels an den Aufrufer zurück. Aus diesem Grund ändert sich der Inhalt der Mitarbeitertabelle nicht.

HINWEIS

Die Anweisungen BEGIN TRANSACTION, COMMIT TRANSACTION und ROLLBACK sind Transact-SQL-Anweisungen für Transaktionen. Diese Anweisungen starten, verpflichten bzw. rollen Transaktionen zurück. In Kapitel 13 finden Sie Erläuterungen zu diesen Aussagen und Transaktionen im Allgemeinen.

0
S.Harshit 22 Feb. 2020 im 17:56

Das Problem hierbei ist, dass die Ausnahme außerhalb des Ausnahmehandlers generiert wird. Die an die Funktion gesendeten Parameter werden überprüft, bevor der Ausnahmebehandler definiert wird. Um diese Ausnahme abzufangen, benötigen Sie einen Ausnahmebehandler für den Aufruf der Funktion.

Wenn Sie p2 varchar (20) deklarieren und die Spaltendefinition varchar (6) beibehalten, könnten Sie wahrscheinlich das gewünschte Verhalten erhalten, da dann die Ausnahme innerhalb des vom Ausnahmehandler abgedeckten Codes ausgelöst würde.

1
Samuel Åslund 22 Feb. 2020 im 21:21