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 SQL