Otázka ukazuje dávkový skript s více příkazy. RAISE_APPLICATION_ERROR() ukončí pouze blok PL/SQL (podprogram), nikoli celý skript (jak poukázal Justin), takže bude pokračovat příkazy, které následují.
Pro dávkové skripty je nejlepší použít WHENEVER SQLERROR EXIT. Ano, je to direktiva SQLPlus, nikoli standardní SQL, ale je poměrně přenosná; nejpopulárnější nástroje Oracle, které podporují skripty, tuto direktivu alespoň částečně podporují. Následující příklad funguje v SQL Plus, SQL*Developer, Toad, SQLsmith a možná další, a demonstruje problém, pokud zakomentujete řádek.
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;
/
Pokud odstraníte WHEN SQLERROR, skript bude pokračovat a provede 2. blok atd., což je přesně to, čemu se má otázka vyhnout.
Výhodou v tomto případě grafických nástrojů, které emulují sqlplus, je to, že skutečně zastavují skript a neodesílají zbytek skriptu do příkazového prostředí jako příkazy prostředí, což se stane, když skripty vložíte do SQLPlus běžící v okně konzoly. SQL Plus se může ukončit při chybě, ale zbývající příkazy s vyrovnávací pamětí pak zvládne shell OS, což je trochu chaotické a potenciálně riskantní, pokud jste měli příkazy shellu v komentářích (což není neslýchané). S SQLPlus je vždy nejlepší se připojit a poté skript spustit nebo jej předat v argumentu příkazového řádku