InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial PL/SQL
Introducción a PLSQL
Programación con PL/SQL
Fundamentos de PL/SQL
Tipos de datos en PL/SQL
Operadores en PL/SQL
Estructuras de control en PL/SQL
Bloques PL/SQL
Cursores en PL/SQL
Cursores Implicitos en PL/SQL
Cursores Explicitos en PL/SQL
Cursores de actualización en PL/SQL
Excepciones en PL/SQL
Excepciones personalizadas en PL/SQL
Propagacion de excepciones en PL/SQL
Subprogramas en PL/SQL
Procedimientos almacenados en PL/SQL
Funciones en PL/SQL
Triggers en PL/SQL
Subprogramas en bloques anónimos
Paquetes en PL/SQL
Registros PL/SQL
Tablas PL/SQL
Tipo VARRAY
BULK COLLECT
Transacciones con PL/SQL
Transacciones autónomas
SQL Dinamico
Funciones integradas de PL/SQL
Secuencias
PL/SQL y Java
También puedes ver ...
Excepciones personalizadas en PL/SQL
Como conectar a ORACLE con Java
Recuperar datos BLOB de ORACLE
Trabajar con datos de tipo BLOB en ORACLE
PL/SQL y Java
Secuencias
Transacciones autónomas
SQL Dinamico
Funciones integradas de PL/SQL
Transacciones con PL/SQL

Afiliados
La Web del programador
MundoProgramacion


 

Excepciones en PL/SQL

Manejo de excepciones

    En PL/SQL una advertencia o condición de error es llamada una excepción.

    Las excepciones se controlan dentro de su propio bloque.La estructura de bloque de una excepción se muestra a continuación.


DECLARE
 -- Declaraciones
BEGIN
  -- Ejecucion
EXCEPTION
  -- Excepcion
END;

    Cuando ocurre un error, se ejecuta la porción del programa marcada por el bloque EXCEPTION, transfiriéndose el control a ese bloque de sentencias.

    El siguiente ejemplo muestra un bloque de excepciones que captura las excepciones NO_DATA_FOUND y ZERO_DIVIDE. Cualquier otra excepcion será capturada en el bloque WHEN OTHERS THEN.


DECLARE
 -- Declaraciones
BEGIN
  -- Ejecucion
EXCEPTION
WHEN NO_DATA_FOUND THEN

  -- Se ejecuta cuando ocurre una excepcion de tipo NO_DATA_FOUND
WHEN ZERO_DIVIDE THEN
  -- Se ejecuta cuando ocurre una excepcion de tipo ZERO_DIVIDE


WHEN OTHERS THEN
  -- Se ejecuta cuando ocurre una excepcion de un tipo no tratado
-- en los bloques anteriores


END;

    Como ya hemos dicho cuando ocurre un error, se ejecuta el bloque EXCEPTION, transfiriéndose el control a las sentencias del bloque. Una vez finalizada la ejecución del bloque de EXCEPTION no se continua ejecutando el bloque anterior.

    Si existe un bloque de excepcion apropiado para el tipo de excepción se ejecuta dicho bloque. Si no existe un bloque de control de excepciones adecuado al tipo de excepcion se ejecutará el bloque de excepcion WHEN OTHERS THEN (si existe!). WHEN OTHERS debe ser el último manejador de excepciones.

    Las excepciones pueden ser definidas en forma interna o explícitamente por el usuario. Ejemplos de excepciones definidas en forma interna son la división por cero y la falta de memoria en tiempo de ejecución. Estas mismas condiciones excepcionales tienen sus propio tipos y pueden ser referenciadas por ellos: ZERO_DIVIDE y STORAGE_ERROR.

    Las excepciones definidas por el usuario deben ser alcanzadas explícitamente utilizando la sentencia RAISE.

    Con las excepciones se pueden manejar los errores cómodamente sin necesidad de mantener múltiples chequeos por cada sentencia escrita. También provee claridad en el código ya que permite mantener las rutinas correspondientes al tratamiento de los errores de forma separada de la lógica del negocio.

Excepciones predefinidas 

    PL/SQL proporciona un gran número de excepciones predefinidas que permiten controlar las condiciones de error más habituales.

    Las excepciones predefinidas no necesitan ser declaradas. Simplemente se utilizan cuando estas son lanzadas por algún error determinado.

    La siguiente es la lista de las excepciones predeterminadas por PL/SQL y una breve descripción de cuándo son accionadas:

Excepcion

Se ejecuta ...

SQLCODE

ACCESS_INTO_NULL El programa intentó asignar valores a los atributos de un objeto no inicializado -6530
COLLECTION_IS_NULL El programa intentó asignar valores a una tabla anidada aún no inicializada -6531
CURSOR_ALREADY_OPEN El programa intentó abrir un cursor que ya se encontraba abierto. Recuerde que un cursor de ciclo FOR automáticamente lo abre y ello no se debe especificar con la sentencia OPEN -6511
DUP_VAL_ON_INDEX El programa intentó almacenar valores duplicados en una columna que se mantiene con restricción de integridad de un índice único (unique index) -1
INVALID_CURSOR El programa intentó efectuar una operación no válida sobre un cursor -1001
INVALID_NUMBER En una sentencia SQL, la conversión de una cadena de caracteres hacia un número falla cuando esa cadena no representa un número válido -1722
LOGIN_DENIED El programa intentó conectarse a Oracle con un nombre de usuario o password inválido -1017
NO_DATA_FOUND Una sentencia SELECT INTO no devolvió valores o el programa referenció un elemento no inicializado en una tabla indexada 100
NOT_LOGGED_ON El programa efectuó una llamada a Oracle sin estar conectado -1012
PROGRAM_ERROR PL/SQL tiene un problema interno -6501
ROWTYPE_MISMATCH Los elementos de una asignación (el valor a asignar y la variable que lo contendrá) tienen tipos incompatibles. También se presenta este error cuando un parámetro pasado a un subprograma no es del tipo esperado -6504
SELF_IS_NULL El parámetro SELF (el primero que es pasado a un método MEMBER) es nulo -30625
STORAGE_ERROR La memoria se terminó o está corrupta -6500
SUBSCRIPT_BEYOND_COUNT El programa está tratando de referenciar un elemento de un arreglo indexado que se encuentra en una posición más grande que el número real de elementos de la colección -6533
SUBSCRIPT_OUTSIDE_LIMIT El programa está referenciando un elemento de un arreglo utilizando un número fuera del rango permitido (por ejemplo, el elemento “-1”) -6532
SYS_INVALID_ROWID La conversión de una cadena de caracteres hacia un tipo rowid falló porque la cadena no representa un número -1410
TIMEOUT_ON_RESOURCE Se excedió el tiempo máximo de espera por un recurso en Oracle -51
TOO_MANY_ROWS Una sentencia SELECT INTO devuelve más de una fila -1422
VALUE_ERROR Ocurrió un error aritmético, de conversión o truncamiento. Por ejemplo, sucede cuando se intenta calzar un valor muy grande dentro de una variable más pequeña -6502
ZERO_DIVIDE El programa intentó efectuar una división por cero -1476

Excepciones definidas por el usuario 

    PL/SQL permite al usuario definir sus propias excepciones, las que deberán ser declaradas y lanzadas explícitamente utilizando la sentencia RAISE.

    Las excepciones deben ser declaradas en el segmento DECLARE de un bloque, subprograma o paquete. Se declara una excepción como cualquier otra variable, asignandole el tipo EXCEPTION. Las mismas reglas de alcance aplican tanto sobre variables como sobre las excepciones.


DECLARE
 -- Declaraciones

MyExcepcion EXCEPTION;
BEGIN
  -- Ejecucion
EXCEPTION
  -- Excepcion
END;

Reglas de Alcance

    Una excepcion es válida dentro de su ambito de alcance, es decir el bloque o programa donde ha sido declarada. Las excepciones predefinidas son siempre válidas.

    Como las variables, una excepción declarada en un bloque es local a ese bloque y global a todos los sub-bloques que comprende.

La sentencia RAISE

    La sentencia RAISE permite lanzar una excepción en forma explícita. Es posible utilizar esta sentencia en cualquier lugar que se encuentre dentro del alcance de la excepción.


DECLARE
 -- Declaramos una excepcion identificada por VALOR_NEGATIVO

VALOR_NEGATIVO EXCEPTION;

valor NUMBER;
BEGIN
  -- Ejecucion

valor := -1;

IF valor < 0 THEN

RAISE VALOR_NEGATIVO;

END IF;


EXCEPTION
  -- Excepcion

WHEN VALOR_NEGATIVO THEN

dbms_output.put_line('El valor no puede ser negativo');
END;

    Con la sentencia RAISE podemos lanzar una excepción definida por el usuario o predefinida, siendo el comportamiento habitual lanzar excepciones definidas por el usuario.

    Recordar la existencia de la excepción OTHERS, que simboliza cualquier condición de excepción que no ha sido declarada. Se utiliza comúnmente para controlar cualquier tipo de error que no ha sido previsto. En ese caso, es común observar la sentencia ROLLBACK en el grupo de sentencias de la excepción o alguna de las funciones SQLCODESQLERRM, que se detallan en el próximo punto.

Uso de SQLCODE y SQLERRM

    Al manejar una excepción es posible usar las funciones predefinidas SQLCode y SQLERRM para aclarar al usuario la situación de error acontecida.

    SQLcode devuelve el número del error de Oracle y un 0 (cero) en caso de exito al ejecutarse una sentencia SQL.

    Por otra parte, SQLERRM devuelve el correspondiente mensaje de error.

    Estas funciones son muy útiles cuando se utilizan en el bloque de excepciones, para aclarar el significado de la excepción OTHERS.

    Estas funciones no pueden ser utilizadas directamente en una sentencia SQL, pero sí se puede asignar su valor a alguna variable de programa y luego usar esta última en alguna sentencia.


DECLARE
  err_num NUMBER;
  err_msg VARCHAR2(255);
result NUMBER;
BEGIN
  SELECT 1/0 INTO result 
FROM DUAL;
 
EXCEPTION 
WHEN OTHERS THEN
 
  err_num := SQLCODE;
  err_msg := SQLERRM;
  DBMS_OUTPUT.put_line('Error:'||TO_CHAR(err_num));
  DBMS_OUTPUT.put_line(err_msg);
END;

    También es posible entregarle a la función SQLERRM un número negativo que represente un error de Oracle y ésta devolverá el mensaje asociado.


DECLARE
  msg VARCHAR2(255);
BEGIN
  msg := SQLERRM(-1403);
  DBMS_OUTPUT.put_line(MSG);
END;

 


Inicio | Tutorial PL/SQL Cursores de actualización en PL/SQLTutorial PL/SQLExcepciones personalizadas en PL/SQL Versión para imprimir Foros de consulta

 
NO_DATA_FOUND por Pablo
Respuesta recibida el [03/07/2007 07:14:49]
Consulta,tengo un trigger en un item boton que dispara una program unit si la tabla tiene datos.....si no tiene datos...el form manda un mensaje de aviso...ahora...el excepcion no_data_found...deberia guardar el mensaje en una variable.....mi problema es que no puedo manejar un ORA 6502/1403, me sale y no me muestra el mensaje....
me podras ayudar?? mi correo es arrobalabase@hotmail.com
Gracias!!!!

 
devolver el control por LumAuro
Respuesta recibida el [08/01/2008 01:40:07]
Muy buen trabajo, ¡felicitaciones!, pero te sugeriría incluir en este capítulo la forma, o formas si hay varias, de devolver el control a la línea que generó la excepción o a la siguiente, de modo que se pueda continuar con la ejecución del código una vez manejada la excepción.

 
Muy fácil por devjoker
Respuesta recibida el [08/01/2008 02:48:59]
Muy fácil, solo hay que anidar bloques

BEGIN
--Hacemos algo
BEGIN
-- Algo que puede generar una excepcion
EXCEPTION WHEN OTHERS THEN
-- Controlamos la excepcion
END;
-- Continuamos con la ejecucion
END;

Pero por favor, para preguntar usad los foros que para eso están!

 
No funciona... por Miguel Guerrero
Respuesta recibida el [25/01/2008 01:54:59]
Muy bien explicado pero no funciona ni madres!!!

Anido los bloques de sentencia y nada

 
Estimado Miguel Guerrero, ante... por Anónimo
Respuesta recibida el [25/01/2008 05:21:38]
Estimado Miguel Guerrero, antes de asegurar que algo no funciona revisa tu código.

 
Estimado Anonimo por Miguel Guerrero
Respuesta recibida el [30/01/2008 05:28:10]
Anonimo si postee el problema es porque esta pasando ya he probado varias cosas y no funciona.

Si no vas a ayudar mejor no vengas a quitarnos el tiempo

Gracias
Saludos

 
Ejemplo cursor con excepcion en dentro por yo misma
Respuesta recibida el [02/04/2008 07:39:57]
Create or Replace Procedure cargarCentrosOficinas is   
CURSOR ccentros
IS
SELECT centro
FROM centros
where tipcentro='OF';


regCentro ccentros%ROWTYPE;
cencontrado varchar2(4);

BEGIN

OPEN ccentros;
FETCH ccentros INTO regCentro;
while ccentros%found
LOOP
BEGIN
select centro into cencontrado
from centrospermitidos
where centro=regCentro.centro ;

dbms_output.put_line( regCentro.centro);

EXCEPTION WHEN NO_DATA_FOUND THEN
insert into centrospermitidos (empprop,centro)
values( 1, regCentro.centro);

commit;
END;
FETCH ccentros INTO regCentro;
END LOOP;
CLOSE ccentros;
END;
/

 
fejocaal@ por Fernando
Respuesta recibida el [05/05/2008 11:21:05]
Muchas gracias por todo. La página me ha sido de gran ayuda en mi proceso de aprendizaje de PL/SQL.


 
procedimiento eliminar por recc
Respuesta recibida el [28/07/2008 08:27:14]
hola quisiera saber que exepciones le podria colocar al procedimiento eliminar, quien sepa infor avisar al correo recc1988@hotmail.com 
gracias

 
hola - sabes como hacer para q... por alberto
Respuesta recibida el [29/08/2008 03:04:04]
hola - sabes como hacer para que la exception simplemente no haga nada, es decir simplemente descarte la operacion sin arrojar un error.
Tengo una situacion donde un proceso externo inserta en una tabla valores que ya existen y quiero que estos inserts simplemente sean descartados.

 
Gracias devjoker, pero en realidad no era pregunta por LumAuro
Respuesta recibida el [10/09/2008 03:20:30]
Antes que nada disculpa por contestar hasta ahora, por casualidad volví a entrar a esta página en particular y encontré tu respuesta.

En realidad no pretendía hacer una consulta sino sugerir la inclusión en el cuerpo principal; es muy común que cuando hablamos del control de errores (excepciones), en cualquier lenguaje, olvidamos hablar sobre el control del flujo de ejecución en caso de error.

Ocurrida la excepción, luego de controlarla, puedes querer reintentar u omitir la instrucción que la desencadenó e incluso un grupo de ellas, y aún creo que ese tema debería formar parte del "Manejo de excepciones". Obviamente, la decisión es tuya.

Un abrazo

 
Exceptions por Diana
Respuesta recibida el [17/09/2008 10:47:33]
Gracias a todos por las respuestas en este foro, me ha sido de gran ayuda... Abrazos.

 
re:hola - sabes como hacer para q... por alberto por martin
Respuesta recibida el [18/11/2008 08:26:58]
Alberto si no queres que haga nada, haces 
exception
when others then
null;
y listo.
slds.

 
ejemplo por leorock
Respuesta recibida el [19/11/2008 02:50:26]
CREATE OR REPLACE PROCEDURE boqueext IS

BEGIN
ejexcepciones;
Dbms_Output.put_line('hola bloke');
exeption
WHEN too_many ROWS THEN
Dbms_Output.put_line('no hay filas');
WHEN OTHERS THEN
Dbms_Output.put_line(SQLERRM);
END;

 
ejemplo2 por leorock
Respuesta recibida el [20/11/2008 03:01:47]
--1. Escribe un procedimiento que calcule los siguientes datos para todos los departamentos:

--********************************
--Nombre:
--Localidad:
--Número:
--Número empleados:
--Salario Total (sin comisiones):
--Salario Total (incl.comisiones):
--Comisiones(% sobre el salario total):
--Media de salarios:
--Nª empleados por debajo de la media:
CREATE OR REPLACE procedure resumendeps IS
CURSOR c IS
SELECT *
FROM departments;

loc location.city%TYPE;
num INTEGER;
media employees.salary%TYPE;
suma employees.salary%TYPE;
sumatotal employees.salary%TYPE;

BEGIN

FOR reg IN c LOOP
SELECT city INTO loc
FROM locations
WHERE location_id=reg.location_id;

Dbms_Output.put_line('departamento'||reg.department_name ||'numero: '||reg.department_id||'ciudad: '||loc);

SELECT Count(*), Nvl(Avg(salary,0)),Nvl(Sum(salary,0)),Nvl(Sum(salary+salary*Nvl(commission_pct,0)),0)
INTO num,media,suma,sumatotal
FROM employees
WHERE department_id=reg.department_id;
--se podria unar un if en lugar de los nvl para que quede mas claro
/*if media is null
media:=0;
end if*/
Dbms_Output.put_line('num empleado: '||num);
Dbms_Output.put_line('salario total: '|| suma);
Dbms_Output.put_line('salario total con comisiones: '||sumatotal);
Dbms_Output.put_line('media salarios: '|| media);

END LOOP;

EXCEPTION
WHEN OTHERS THEN
Dbms_Output.put_line('error: '||SQLERRM);
END;

 
only comment por Queimporta
Respuesta recibida el [17/12/2008 12:15:05]
como suele ocurrir, aca se encuentra toda la gama de personajes q uno encuentra en el laburo.
los q se peinan con el codigo y estan muy dados a regalar su conocimiento.
los q no saben un pepino y quieren q les hagan la tarea y por supuesto, el codigo, la maquina o el compañero tiene la culpa.
he encontrado excelente el curso, va avanzando lentamente internalizandote con aspectos mas complejos del lenguaje, sugiriendo y recordando aspectos claves del diseño como recordar q un UPDATE bloquea la tabla, muy bien incluido el comentario.
pero como en el laburo, tenemos q soportar a esos clasicos tarados incapaces de arreglar un grifo o destapar un caño y q para todo tienen como solucion el clasico: "tu tienes la culpa", debieramos hacer un gran foro para apuntar a esos inutiles y cagarlos profesionalmente.


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial PL/SQL Cursores de actualización en PL/SQLTutorial PL/SQLExcepciones personalizadas en PL/SQL Versión para imprimir

Excepciones en PL/SQL
Autor: Pedro Herrarte Sánchez
Visitas: 71060 Fecha de publicación: 28/06/2006
Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación.

Posee mas de diez años de experiencia trabajando para las principales empresas de España.

Es especialista en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas.

Es experto en desarrollo (C#, ASP.NET, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE).

Es fundador, diseñador y programador de www.devjoker.com.




Visitas: 45 | Comentarios: 0 | Archivo: Articulos
Visitas: 109 | Comentarios: 0 | Archivo: Articulos
Visitas: 156 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 34 | Comentarios: 0 | Archivo: Articulos
Categorias: TFS
Visitas: 285 | Comentarios: 1 | Archivo: Articulos
Categorias: Visual Basic .NET|C#
Visitas: 842 | Comentarios: 2 | Archivo: Articulos
Categorias: C#|ASP.NET|HTML DHTML|XML|JavaScript|ASP.NET|ASP|PHP|Visual Studio
Visitas: 712 | Comentarios: 1 | Archivo: Articulos
Categorias: Administración|Tutorial SQL
Visitas: 451 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 1054 | Comentarios: 1 | Archivo: Articulos
Categorias: ASP.NET|CSS|ASP.NET
Visitas: 250 | Comentarios: 0 | Archivo: Articulos
Categorias: TFS

Útimos temas recibidos en los foros ...
FORMULARIO ACCESS por jcifuentes ... [Access] 11 29/05/2007
Ysmael por Ysmael ... [SQL] 0 08/01/2009
Reflection por Maurito22 ... [C#] 2 06/01/2009
Programador por Robert ... [ORACLE] 0 07/01/2009
como insertar registros en un formulario de visual basic.net desde la base de datos sql server por orlan ... [SQL Server] 8 09/06/2008
quierocodigo de autogenerado del seguro por edwin garcia ramirez ... [Visual Basic .NET] 0 07/01/2009
Video gratis sobre AJAX con ASP.NET por alexxe ... [ASP.NET] 1 06/01/2009
calcular saldo acumulativo por cben ... [SQL] 5 30/12/2008
comparar 2 campos de 2 tablas usando el like por nani ... [SQL Server] 1 06/01/2009
Apagar ordenador remoto en C# por victoryiyo ... [C#] 1 07/01/2009
numero de AUTOGENERADO IPSS por carlos ... [Visual Basic .NET] 5 30/10/2008
Como mandar mensaje a Celular por Pako ... [C#] 63 13/03/2007

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
28/06/2006 Propagacion de excepciones en PL/SQL    forma parte de...Tutorial PL/SQL
04/12/2006 Definición de punteros    forma parte de...Tutorial C#
02/10/2006 La clase System.Array    forma parte de...Tutorial C#
02/10/2006 Tablas multidimensionales    forma parte de...Tutorial C#
09/10/2006 Variables y tipos de datos    forma parte de...Tutorial C#
09/11/2006 Interfaces    forma parte de...Tutorial C#
19/09/2007 Triggers en Transact SQL    forma parte de...Tutorial de Transact SQL
03/10/2006 Fundamentos de C#    forma parte de...Tutorial C#
03/10/2006 Estrcuturas de control.    forma parte de...Tutorial C#
22/10/2005 Insertar datos. INSERT    forma parte de...Tutorial SQL

 

Encuesta
¿A que perfil te adaptas mejor?
[Ver] [Votar]