sql >> Base de Datos >  >> RDS >> Oracle

PL/SQL:¿hay alguna instrucción para detener por completo la ejecución del script?

La pregunta muestra un script por lotes de varias declaraciones. RAISE_APPLICATION_ERROR() solo sale de un bloque PL/SQL (subprograma), no del script general (como lo señaló Justin), por lo que continuará con las declaraciones que siguen.

Para secuencias de comandos por lotes, es mejor usar SIEMPRE QUE SALGA SQLERROR. Sí, es una directiva SQLPlus, no SQL estándar, pero es bastante portátil; Las herramientas de Oracle más populares que admiten scripts admiten esta directiva, al menos parcialmente. El siguiente ejemplo funciona en SQL Además, SQL*Developer, Toad, SQLsmith y posiblemente otros, y demuestra el problema, si comenta la línea.

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

Si elimina WHEN SQLERROR, la secuencia de comandos continuará y ejecutará el segundo bloque, etc., que es exactamente lo que la pregunta pide evitar.

La ventaja, en este caso, de las herramientas gráficas que emulan sqlplus es que realmente detienen el script y no envían el resto del script al shell de comandos como comandos de shell, que es lo que sucede si pega scripts en SQLPlus ejecutándose en una ventana de consola. SQL Plus puede salir por error, pero los comandos almacenados en búfer restantes serán manejados por el shell del sistema operativo, lo cual es un poco complicado y potencialmente riesgoso, si tenía comandos de shell en los comentarios (lo cual no es inaudito). Con SQLPlus, siempre es mejor conectarse y luego ejecutar el script, o pasarlo en el argumento de la línea de comando (sqlplus scott/tiger @foo.sql) para evitar esto.