Pytanie przedstawia skrypt wsadowy zawierający wiele instrukcji. RAISE_APPLICATION_ERROR() wychodzi tylko z bloku PL/SQL (podprogramu), a nie z całego skryptu (jak wskazał Justin), więc będzie kontynuowane z następującymi instrukcjami.
W przypadku skryptów wsadowych najlepiej jest używać WHENEVER SQLERROR EXIT. Tak, jest to dyrektywa SQLPlus, a nie standardowy SQL, ale jest dość przenośna; najpopularniejsze narzędzia Oracle obsługujące skrypty obsługują tę dyrektywę, przynajmniej częściowo. Poniższy przykład działa w SQL Dodatkowo, SQL*Developer, Toad, SQLsmith i być może inni, i zademonstruje problem, jeśli skomentujesz ten wiersz.
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;
/
Jeśli usuniesz WHEN SQLERROR, skrypt będzie kontynuował i wykona drugi blok itd., czego dokładnie prosi pytanie, aby uniknąć.
Zaletą w tym przypadku narzędzi graficznych, które emulują sqlplus, jest to, że naprawdę zatrzymują skrypt i nie przesyłają pozostałej części skryptu do powłoki poleceń jako poleceń powłoki, co dzieje się, jeśli wkleisz skrypty do SQLPlus działa w oknie konsoli. SQL Plus może zakończyć działanie w przypadku błędu, ale pozostałe buforowane polecenia będą wtedy obsługiwane przez powłokę systemu operacyjnego, co jest nieco niechlujne i potencjalnie ryzykowne, jeśli masz polecenia powłoki w komentarzach (co nie jest niespotykane). W przypadku SQLPlus zawsze najlepiej jest połączyć się, a następnie wykonać skrypt lub przekazać go w argumencie wiersza poleceń