Manejo de excepciones en Oracle PL/SQL (Ejemplos)

โšก Resumen inteligente

Manejo de excepciones en Oracle PL/SQL captura los errores de tiempo de ejecuciรณn que impiden la ejecuciรณn de un bloque, lo que permite al motor transferir el control a una secciรณn EXCEPTION donde los manejadores predefinidos, definidos por el usuario y OTHERS responden, generan o propagan errores de forma segura.

  • โš™๏ธ Errores en tiempo de ejecuciรณn: Se produce una excepciรณn cuando el motor PL/SQL encuentra una instrucciรณn que no puede ejecutar, como por ejemplo dividir un nรบmero entre cero.
  • ๐Ÿงฑ Estructura de bloques: Las excepciones se gestionan en la secciรณn EXCEPTION mediante clรกusulas WHEN, y WHEN OTHERS siempre se coloca al final.
  • ๐Ÿ“š Excepciones predefinidas: Oracle Nombra errores comunes como NO_DATA_FOUND y ZERO_DIVIDE en el paquete STANDARD, listos para ser capturados directamente.
  • ๐Ÿ› ๏ธ Excepciones definidas por el usuario: Los programadores declaran sus propias variables de EXCEPCIร“N y las generan explรญcitamente con la palabra clave RAISE.
  • โฌ†๏ธ Propagaciรณn: Una excepciรณn no controlada pasa al bloque que la contiene, y RAISE la vuelve a notificar al programa padre.
  • ๐Ÿค– Asistencia de IA: Las herramientas de codificaciรณn de IA elaboran bloques de EXCEPCIร“N y seรฑalan las rutas de error no controladas durante la revisiรณn.

Manejo de excepciones en Oracle PL / SQL

ยฟQuรฉ es el manejo de excepciones en PL/SQL?

Se produce una excepciรณn cuando el motor PL/SQL encuentra una instrucciรณn que no puede ejecutar debido a un error que surge en tiempo de ejecuciรณn. Estos errores no se detectan en tiempo de compilaciรณn y, por lo tanto, deben gestionarse รบnicamente en tiempo de ejecuciรณn.

Por ejemplo, si el motor PL/SQL recibe una instrucciรณn para dividir un nรบmero entre cero, genera una excepciรณn. Esta excepciรณn solo se genera en tiempo de ejecuciรณn por el motor PL/SQL.

Una excepciรณn impide que el programa continรบe ejecutรกndose, por lo que, para evitar esta situaciรณn, es necesario capturar y gestionar el error por separado. Este proceso se denomina manejo de excepciones, en el que el programador gestiona el error que puede ocurrir durante la ejecuciรณn.

Sintaxis de manejo de excepciones

Las excepciones se gestionan a nivel de bloque. Cuando se produce una excepciรณn en un bloque, el control abandona la parte de ejecuciรณn de dicho bloque y la excepciรณn se gestiona en la secciรณn de manejo de excepciones. Una vez gestionada la excepciรณn, el control no puede regresar a la secciรณn de ejecuciรณn del mismo bloque.

La siguiente ilustraciรณn muestra cรณmo la secciรณn de ejecuciรณn y la secciรณn de manejo de excepciones se ubican dentro de un รบnico bloque PL/SQL:

Estructura de un bloque PL/SQL con una secciรณn de ejecuciรณn y una secciรณn de excepciones.

La sintaxis que se muestra a continuaciรณn explica cรณmo capturar y gestionar una excepciรณn.

BEGIN
<execution block>
.
.
EXCEPTION
WHEN <exceptionl_name>
THEN
  <Exception handling code for the โ€œexception 1 _nameโ€™' >
WHEN OTHERS
THEN
  <Default exception handling code for all exceptions >
END;

Explicaciรณn de sintaxis:

  • En la sintaxis anterior, el bloque de manejo de excepciones contiene una serie de condiciones WHEN para manejar las excepciones.
  • Cada condiciรณn WHEN va seguida de un nombre de excepciรณn que se espera que se genere en tiempo de ejecuciรณn.
  • Cuando se produce una excepciรณn en tiempo de ejecuciรณn, el motor PL/SQL busca esa excepciรณn en particular en la secciรณn de manejo de excepciones, comenzando por la primera clรกusula WHEN y avanzando secuencialmente.
  • Si encuentra un controlador para la excepciรณn que se generรณ, ejecuta el cรณdigo de ese controlador en particular.
  • Si ninguna clรกusula WHEN coincide con la excepciรณn generada, el motor PL/SQL ejecuta la parte WHEN OTHERS, si estรก presente. Este manejador es comรบn a todas las excepciones.
  • Una vez ejecutado el controlador, el control abandona el bloque actual.
  • Solo se puede ejecutar un controlador de excepciones por bloque en tiempo de ejecuciรณn. Una vez ejecutado, el motor omite los controladores restantes y abandona el bloque actual.

Nota: La instrucciรณn WHEN OTHERS siempre debe colocarse al final de la secuencia. Cualquier controlador escrito despuรฉs de WHEN OTHERS nunca se ejecuta, ya que el control sale del bloque una vez que WHEN OTHERS se ha ejecutado.

Tipos de excepciรณn

Hay dos tipos de excepciones en PL / SQL.

  • Excepciones predefinidas
  • Excepciones definidas por el usuario

Excepciones predefinidas

Oracle tiene predefinidas algunas excepciones comunes. Cada excepciรณn predefinida tiene un nombre y un nรบmero de error รบnicos, y todas ellas estรกn declaradas en el paquete STANDARD en OracleEn el cรณdigo, puede usar estos nombres de excepciones predefinidos directamente para manejar los errores correspondientes. Muchos de ellos se corresponden directamente con excepciones comunes. SQL errores con los que te encuentras todos los dรญas.

A continuaciรณn se presentan algunas excepciones predefinidas:

Excepciรณn Error Code Razรณn de excepciรณn
ACCESO_INTO_NULL ORA-06530 Asignar un valor a los atributos de un objeto no inicializado.
CASO_NO_ENCONTRADO ORA-06592 Ninguna de las clรกusulas WHEN en una instrucciรณn CASE se cumple y no se especifica ninguna clรกusula ELSE.
COLLECTION_IS_NULL ORA-06531 Utilizar mรฉtodos de colecciรณn (excepto EXISTS) o acceder a atributos de colecciรณn en una colecciรณn no inicializada.
CURSOR_ALREADY_OPEN ORA-06511 Tratando de abrir un cursor que ya estรก abierto
DUP_VAL_ON_INDEX ORA-00001 Almacenar un valor duplicado en una columna de base de datos que estรก restringida por un รญndice รบnico.
INVALID_CURSOR ORA-01001 Operaciones ilegales con el cursor, como cerrar un cursor que no estรก abierto.
NรšMERO INVALIDO ORA-01722 La conversiรณn de un carรกcter a un nรบmero fallรณ debido a un carรกcter numรฉrico no vรกlido.
DATOS NO ENCONTRADOS ORA-01403 Una sentencia SELECT que contiene una clรกusula INTO no recupera ninguna fila.
ROW_MISCATCH ORA-06504 El tipo de datos de la variable cursor es incompatible con el tipo de retorno real del cursor.
SUBSCRIPT_BEYOND_COUNT ORA-06533 Referenciar una colecciรณn mediante un nรบmero de รญndice mayor que el tamaรฑo de la colecciรณn.
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 Referenciar una colecciรณn mediante un nรบmero de รญndice fuera del rango legal (por ejemplo, -1).
TOO_MANY_ROWS ORA-01422 Una instrucciรณn SELECT con una clรกusula INTO devuelve mรกs de una fila.
VALOR_ERROR ORA-06502 Un error aritmรฉtico o de restricciรณn de tamaรฑo (por ejemplo, asignar un valor mayor que el tamaรฑo de la variable).
ZERO_DIVIDE ORA-01476 Dividir un nรบmero entre cero

Excepciรณn definida por el usuario

Ademรกs de las excepciones predefinidas mencionadas anteriormente, un programador puede crear excepciones personalizadas y gestionarlas. Estas se crean a nivel de subprograma, en la secciรณn de declaraciรณn, y solo son visibles dentro de dicho subprograma. Una excepciรณn definida en la especificaciรณn de un paquete es una excepciรณn pรบblica y es visible desde cualquier lugar donde se pueda acceder al paquete.

Sintaxis: A nivel de subprograma

DECLARE
<exception_name> EXCEPTION;
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;
  • En la sintaxis anterior, la variable 'exception_name' se define como de tipo EXCEPTION.
  • Posteriormente, puede utilizarse del mismo modo que una excepciรณn predefinida.

Sintaxis: A nivel de especificaciรณn del paquete

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • En la sintaxis anterior, la variable 'exception_name' se define como el tipo EXCEPTION en la especificaciรณn del paquete de .
  • Se puede utilizar en toda la base de datos dondequiera que se pueda llamar al paquete 'package_name'.

Excepciรณn de aumento de PL/SQL

Todas las excepciones predefinidas se generan implรญcitamente cuando se produce el error correspondiente. Sin embargo, las excepciones definidas por el usuario deben generarse explรญcitamente mediante la palabra clave RAISE. RAISE se puede utilizar de las formas que se muestran a continuaciรณn.

Si se utiliza RAISE de forma independiente dentro de un manejador, propaga la excepciรณn ya generada al bloque padre. Solo se puede utilizar dentro de un bloque de excepciones, como se muestra a continuaciรณn.

La captura de pantalla que aparece a continuaciรณn muestra cรณmo se utiliza RAISE de forma aislada para volver a lanzar una excepciรณn en el bloque que la contiene:

Propagaciรณn de una excepciรณn al bloque padre con un RAISE simple

CREATE [ PROCEDURE | FUNCTION ]
 AS
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN
             <Handler>
RAISE;
END;

Explicaciรณn de sintaxis:

  • En la sintaxis anterior, la palabra clave RAISE se utiliza dentro del bloque de manejo de excepciones.
  • Siempre que el programa encuentre la excepciรณn 'exception_name', esta se gestionarรก y finalizarรก con normalidad.
  • La palabra clave RAISE en el manejador propaga entonces esa misma excepciรณn al programa padre.

Nota: Al generar una excepciรณn en el bloque padre, la excepciรณn que se genera tambiรฉn debe ser visible en el bloque padre; de โ€‹โ€‹lo contrario Oracle arroja un error.

Tambiรฉn puede usar la palabra clave RAISE seguida del nombre de la excepciรณn para generar esa excepciรณn especรญfica, ya sea definida por el usuario o predefinida. Este formato se puede usar tanto en la ejecuciรณn como en el manejo de excepciones.

La captura de pantalla que aparece a continuaciรณn muestra RAISE seguido del nombre de una excepciรณn para generar una excepciรณn especรญfica:

Generar una excepciรณn especรญfica con nombre usando RAISE seguido del nombre de la excepciรณn.

CREATE [ PROCEDURE | FUNCTION ]
AS
BEGIN
<Execution block>
RAISE <exception_name>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;

Explicaciรณn de sintaxis:

  • En la sintaxis anterior, la palabra clave RAISE se usa en la parte de ejecuciรณn, seguida de la excepciรณn 'exception_name'.
  • Esto genera esa excepciรณn en particular en tiempo de ejecuciรณn, y luego debe ser manejada o generada nuevamente.

Ejemplo 1: En este ejemplo veremos:

  • Cรณmo declarar una excepciรณn
  • Cรณmo generar la excepciรณn declarada
  • Cรณmo propagarlo al bloque principal.

La captura de pantalla que aparece a continuaciรณn muestra el bloque completo que declara sample_exception, lo genera dentro de un bloque anidado y lo propaga al bloque principal:

Ejemplo de PL/SQL para declarar y generar una excepciรณn definida por el usuario en un bloque anidado.

La siguiente captura de pantalla muestra la continuaciรณn del mismo ejemplo, donde el bloque principal finalmente captura la excepciรณn propagada:

Salida que muestra la excepciรณn capturada primero en el bloque anidado y luego en el bloque principal.

DECLARE
Sample_exception EXCEPTION;
PROCEDURE nested_block
IS
BEGIN
Dbms_output.put_line('Inside nested block');
Dbms_output.put_line('Raising sample_exception from nested block');
RAISE sample_exception;
EXCEPTION
WHEN sample_exception THEN
Dbms_output.put_line ('Exception captured in nested block. Raising to main block');
RAISE;
END;
BEGIN
Dbms_output.put_line('Inside main block');
Dbms_output.put_line('Calling nested block');
Nested_block;
EXCEPTION
WHEN sample_exception THEN
Dbms_output.put_line ('Exception captured in main block');
END;
/

Code Explicaciรณn:

  • Code lรญnea 2: Declarar la variable 'sample_exception' como de tipo EXCEPTION.
  • Code lรญnea 3: Declarando el procedimiento nested_block.
  • Code lรญnea 6: Imprimiendo la instrucciรณn โ€œDentro del bloque anidadoโ€.
  • Code lรญnea 7: Imprimiendo el mensaje โ€œGenerando sample_exception desde bloque anidadoโ€.
  • Code lรญnea 8: Generar la excepciรณn usando 'RAISE sample_exception'.
  • Code lรญnea 10: Manejador de excepciones para la excepciรณn sample_exception en el bloque anidado.
  • Code lรญnea 11: Imprimiendo el mensaje โ€œExcepciรณn capturada en el bloque anidado. Elevando al bloque principalโ€.
  • Code lรญnea 12: Generando la excepciรณn en el bloque principal (propagรกndola).
  • Code lรญnea 15: Imprimiendo la instrucciรณn โ€œDentro del bloque principalโ€.
  • Code lรญnea 16: Imprimiendo la declaraciรณn "Llamando al bloque anidado".
  • Code lรญnea 17: Llamando al procedimiento nested_block.
  • Code lรญnea 19: Manejador de excepciones para sample_exception en el bloque principal.
  • Code lรญnea 20: Imprimiendo el mensaje โ€œExcepciรณn capturada en el bloque principalโ€.

Puntos importantes a tener en cuenta en la excepciรณn

  • En una funciรณn, una excepciรณn siempre debe devolver un valor o generar la excepciรณn; de lo contrario, Oracle Genera un error de "La funciรณn devolviรณ un valor" en tiempo de ejecuciรณn.
  • Estados de control de transacciones puede emitirse dentro del bloque de manejo de excepciones.
  • SQLERRM y SQLCODE son funciones integradas que devuelven el mensaje de excepciรณn y el cรณdigo de excepciรณn, respectivamente.
  • Si no se gestiona una excepciรณn, por defecto todas las transacciones activas en esa sesiรณn se revierten.
  • GENERAR_ERROR_DE_APLICACIร“N (- , ) se puede usar en lugar de RAISE para generar un error con un cรณdigo y un mensaje personalizados. El cรณdigo de error debe estar entre -20000 y -20999.

Preguntas Frecuentes

PRAGMA EXCEPTION_INIT asocia un nombre de excepciรณn declarado por el usuario con una excepciรณn especรญfica. Oracle Nรบmero de error. Despuรฉs de la vinculaciรณn, puede capturar ese error ORA por nombre en una clรกusula WHEN en lugar de usar WHEN OTHERS y verificar SQLCODE.

SQLCODE devuelve el cรณdigo de error numรฉrico de la excepciรณn actual, mientras que SQLERRM devuelve su mensaje de texto. Ambas se llaman dentro de un manejador de excepciones, generalmente en el bloque WHEN OTHERS, para registrar o mostrar quรฉ saliรณ mal.

Evite usar WHEN OTHERS, que ignora todos los errores silenciosamente. Al no registrar SQLCODE ni SQLERRM ni volver a lanzar la excepciรณn con RAISE, oculta los errores. รšselo solo para registrar, limpiar y propagar la excepciรณn.

RAISE_APPLICATION_ERROR acepta un nรบmero de error entre -20000 y -20999 y un mensaje de hasta 2048 bytes. Detiene la ejecuciรณn y devuelve un error personalizado a la aplicaciรณn que la llama, haciendo que una condiciรณn definida por el usuario parezca una condiciรณn nativa. Oracle error.

No en el mismo bloque: una vez que el control pasa a la secciรณn EXCEPTION, ese bloque finaliza. Para continuar, envuelva la instrucciรณn de riesgo en un bloque interno BEGINโ€ฆEXCEPTIONโ€ฆEND; despuรฉs de que este maneje el error, el bloque externo continรบa ejecutรกndose.

Un error es cualquier problema de ejecuciรณn o compilaciรณn en el cรณdigo. Una excepciรณn es el mecanismo de ejecuciรณn de PL/SQL que representa un error de ejecuciรณn, transfiriendo el control a la secciรณn EXCEPTION para que el programa pueda responder en lugar de terminar abruptamente.

Sรญ. Los asistentes de IA y los revisores de cรณdigo de aprendizaje automรกtico elaboran bloques de EXCEPCIร“N, sugieren quรฉ excepciones predefinidas capturar e identifican las rutas de cรณdigo que carecen de manejadores. Aun asรญ, el desarrollador debe confirmar la lรณgica y los mensajes de error antes de la implementaciรณn.

Copiloto de GitHub Completa automรกticamente las clรกusulas WHEN, las llamadas a RAISE_APPLICATION_ERROR y los bloques EXCEPTION completos a partir de un breve comentario que describe la intenciรณn. Acelera la codificaciรณn de manejadores rutinarios, aunque los cรณdigos y mensajes de error generados requieren revisiรณn para verificar su precisiรณn.

Resumir este post con: