Oracle
 sql >> Datenbank >  >> RDS >> Oracle

PL/SQL:Gibt es eine Anweisung, die Skriptausführung vollständig zu stoppen?

Die Frage zeigt ein Stapelskript mit mehreren Anweisungen. RAISE_APPLICATION_ERROR() wird nur aus einem PL/SQL-Block (Unterprogramm) beendet, nicht aus dem gesamten Skript (wie von Justin hervorgehoben), sodass es mit den folgenden Anweisungen fortgesetzt wird.

Für Stapelskripte ist es am besten, WHENEVER SQLERROR EXIT zu verwenden. Ja, es ist eine SQLPlus-Anweisung, kein Standard-SQL, aber ziemlich portabel; Die gängigsten Oracle-Tools, die Skripte unterstützen, unterstützen diese Direktive zumindest teilweise. Das folgende Beispiel funktioniert in SQL Plus, SQL*Developer, Toad, SQLsmith und möglicherweise andere, und demonstriert das Problem, wenn Sie die Zeile auskommentieren.

set serveroutput on

-- Without this line, things keep going
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;

BEGIN
  IF (1 > 0) THEN
    DBMS_OUTPUT.PUT_LINE('First thing');
    RAISE_APPLICATION_ERROR(-20000, 'Test failed'); -- not enough
  END IF;
END;
/

-- This will execute if you remove WHEN SQLERROR.., so RAISE_APPLICATION_ERROR is not enough
BEGIN
   DBMS_OUTPUT.PUT_LINE('Second thing - Executes anyway');
END;
/

Wenn Sie WHEN SQLERROR entfernen, fährt das Skript fort und führt den 2. Block usw. aus, was genau das ist, was die Frage vermeiden soll.

In diesem Fall haben grafische Tools, die sqlplus emulieren, den Vorteil, dass sie das Skript wirklich stoppen und den Rest des Skripts nicht als Shell-Befehle an die Befehlsshell senden, was passiert, wenn Sie Skripts in SQLPlus läuft in einem Konsolenfenster. SQL Plus kann bei einem Fehler beendet werden, aber die verbleibenden gepufferten Befehle werden dann von der OS-Shell behandelt, was etwas chaotisch und potenziell riskant ist, wenn Sie Shell-Befehle in den Kommentaren hatten (was nicht ungewöhnlich ist). Bei SQLPlus ist es immer am besten, eine Verbindung herzustellen und dann das Skript auszuführen oder es im Befehlszeilenargument (sqlplus scott/tiger @foo.sql) zu übergeben, um dies zu vermeiden.