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.

ยฟ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:
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:
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:
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:
La siguiente captura de pantalla muestra la continuaciรณn del mismo ejemplo, donde el bloque principal finalmente captura la excepciรณn propagada:
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.





