Saltar al contenido

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

Necesitamos tu apoyo para compartir nuestros tutoriales con relación a las ciencias informáticas.

Solución:

La pregunta muestra un script por lotes de varias instrucciones. 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 un SQLDirectiva Plus, 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 SQLAdemá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 SQL.Además de ejecutarse en una ventana de consola. sqlPlus 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 < start > argumento de línea de comando (sqlplus scott/tiger @foo.sql) para evitar esto.

Si no desea generar una excepción, puede intentar algo como (no probado):

declare
  SOME_COUNT INTEGER;
begin
  SELECT COUNT(*) INTO SOME_COUNT FROM SOME_TABLE WHERE ;
  IF (SOME_COUNT > 0) THEN
    DBMS_OUTPUT.PUT_LINE('Test failed, I don''want the rest of the script'
      || ' to be executed.');

    goto end_proc;
  END IF;

  -- A bunch of great code here

  <>
  null;  -- this could be a commit or other lines of code
end;

Algunas personas odian las declaraciones GOTO, ya que pueden conducir a un código espagueti si se abusa de ellas, pero en situaciones simples como esta (nuevamente, suponiendo que no desea generar una excepción) funcionan bien en mi opinión.

Unos segundos más de googlear me dieron la respuesta: la función RAISE_APPLICATION_ERROR()

  IF (SOME_COUNT > 0) THEN
    RAISE_APPLICATION_ERROR(-20000, 'Test failed');
  END IF;

El código de error definido por el usuario debe estar entre -20000 y -20999.

Detalles sobre el documento de Oracle aquí: http://docs.oracle.com/cd/B10501_01/appdev.920/a96624/07_errs.htm#877 (sección Definición de sus propios mensajes de error: Procedimiento RAISE_APPLICATION_ERROR)

Te mostramos comentarios y calificaciones

Más adelante puedes encontrar las observaciones de otros sys admins, tú asimismo tienes la libertad de insertar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *