Oracle
 sql >> Database >  >> RDS >> Oracle

PL/SQL:esiste un'istruzione per interrompere completamente l'esecuzione dello script?

La domanda mostra uno script batch con più istruzioni. RAISE_APPLICATION_ERROR() esce solo da un blocco PL/SQL (sottoprogramma), non dallo script generale (come sottolineato da Justin), quindi continuerà con le istruzioni che seguono.

Per gli script batch, è meglio usare QUANDO SQLERROR EXIT. Sì, è una direttiva SQLPlus, non SQL standard, ma è abbastanza portabile; gli strumenti Oracle più diffusi che supportano gli script supportano questa direttiva, almeno in parte. L'esempio seguente funziona in SQL Inoltre, SQL*Developer, Toad, SQLsmith e possibilmente altri, e dimostra il problema, se commenti la riga.

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;
/

Se rimuovi WHEN SQLERROR, lo script continuerà ed eseguirà il 2° blocco, ecc., che è esattamente ciò che la domanda chiede di evitare.

Il vantaggio, in questo caso, degli strumenti grafici che emulano sqlplus, è che interrompono davvero lo script e non inviano il resto dello script alla shell dei comandi come comandi della shell, cosa che accade se si incollano gli script in SQLPlus in esecuzione in una finestra della console. SQL Plus potrebbe uscire in caso di errore, ma i restanti comandi memorizzati nel buffer verranno quindi gestiti dalla shell del sistema operativo, che è un po' disordinata e potenzialmente rischiosa, se nei commenti sono presenti comandi della shell (cosa non inaudita). Con SQLPlus, è sempre meglio connettersi, quindi eseguire lo script o passarlo nell'argomento della riga di comando (sqlplus scott/tiger @foo.sql) per evitarlo.