Manejo de Excepciones (Errores de tiempo de ejecución)

Puede manejar excepciones que se producen en tiempo de ejecución con código PL/SQL.

Consulte también: Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre el manejo de errores PL/SQL

Acerca de las Excepciones y los Manejadores de Excepciones

Cuando se produce un error de tiempo de espera en el código PL/SQL, se emite una excepción. Si el subprograma (o bloque) en el que se emite la excepción tiene una parte de manejo de excepciones, el control las transferencias que se realizan a ella; de lo contrario, la ejecución parará.

Los errores de Tiempo de Ejecución se pueden producir por los fallos del diseño, los errores de codificación, los fallos del hardware y muchas otras fuentes.

Oracle Database tiene muchas excepciones predefinidas , que se emite automáticamente cuando un programa viola las reglas de la base de datos o excede los límites dependientes del sistema. Por ejemplo, si una sentencia SELECT INTO no devuelve ninguna línea, Oracle Database emite la excepción predefinida NO_DATA_FOUND. Para obtener un resumen de las excepciones PL/SQL predefinidas, consulte Referencia de lenguaje PL/SQL de Oracle Database.

PL/SQL le deja definir (declarar) sus propias excepciones. Una declaración de excepción tiene la siguientes sintaxis:

exception_name EXCEPTION;

A diferencia de una excepción predefinida, se debe emitir una excepción definida por usuario de forma explícita mediante la sentencia RAISE o el procedimiento DBMS_STANDARD.RAISE_APPLICATION_ERROR. Por ejemplo:

IF condition THEN RAISE exception_name;

Para obtener información sobre el procedimiento DBMS_STANDARD.RAISE_APPLICATION_ERROR, consulte Referencia de lenguaje PL/SQL de Oracle Database.

La parte que maneja excepciones de un subprograma contiene uno o más manejadores de excepciones. Un manejador de excepciones tiene la siguiente sintaxis:

WHEN { exception_name [ OR exception_name ]... | OTHERS } THEN
  statement; [ statement; ]...

("Acerca de la Estructura de Subprograma" muestra dónde colocar la parte de manejo de excepciones de un subprograma).

Un identificador de excepciones WHEN OTHERS maneja errores de tiempo de ejecución inesperados. Si se utiliza, debe ser último. Por ejemplo:

EXCEPTION
  WHEN exception_1 THEN
    statement; [ statement; ]...
  WHEN exception_2 OR exception_3 THEN
    statement; [ statement; ]...
  WHEN OTHERS THEN
    statement; [ statement; ]...
    RAISE;  -- Reraise the exception (very important).
END;

Una alternativa al manejador de excepciones WHEN OTHERS es el pragma EXCEPTION_INIT que asocia un nombre de excepción definida por el usuario a un número Oracle Database.

Consulte además:

Cuándo Utilizar Manejadores de Excepciones

Utilice manejadores de excepciones solo en las siguientes situaciones.

Manejo de Excepciones Predefinidas

Puede gestionar excepciones predefinidas. En el Ejemplo 5-13 se muestra cómo cambiar el procedimiento EMP_EVAL.EVAL_DEPARTMENT para manejar la excepción predefinida NO_DATA_FOUND. Realice este cambio y compile el procedimiento cambiado. (Para ver un ejemplo de cómo cambiar el cuerpo del paquete, consulte "Tutorial: Declaración de Variables y Constantes en un Subprograma".)

Ejemplo 5-13 Manejo de la Excepción Predefinida NO_DATA_FOUND

PROCEDURE eval_department(dept_id IN employees.department_id%TYPE) AS
  emp_cursor    emp_refcursor_type;
  current_dept  departments.department_id%TYPE;

BEGIN
  current_dept := dept_id;

  FOR loop_c IN 1..3 LOOP
    OPEN emp_cursor FOR
      SELECT *
      FROM employees
      WHERE current_dept = eval_department.dept_id;

    DBMS_OUTPUT.PUT_LINE
      ('Determining necessary evaluations in department #' ||
       current_dept);

    eval_loop_control(emp_cursor);

    DBMS_OUTPUT.PUT_LINE
      ('Processed ' || emp_cursor%ROWCOUNT || ' records.');

    CLOSE emp_cursor;
    current_dept := current_dept + 10;
  END LOOP;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('The query did not return a result set');
END eval_department;

Consulte también: Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre las excepciones predefinidas

Declaración y Manejo de Excepciones Definidas por el Usuario

Puede declarar y manejar excepciones definidas por el usuario. En el ejemplo 5-14 se muestra cómo cambiar la función EMP_EVAL.CALCULATE_SCORE para declarar y manejar dos excepciones definidas por el usuario, bad_weight y bad_score. Realice este cambio y compile la función cambiada. (Para ver un ejemplo de cómo cambiar el cuerpo del paquete, consulte "Tutorial: Declaración de Variables y Constantes en un Subprograma".)

Ejemplo 5-14 Manejo de excepciones definidas por el usuario

FUNCTION calculate_score ( evaluation_id IN scores.evaluation_id%TYPE
                         , performance_id IN scores.performance_id%TYPE )
                         RETURN NUMBER AS

  weight_wrong  EXCEPTION;
  score_wrong   EXCEPTION;
  n_score       scores.score%TYPE;
  n_weight      performance_parts.weight%TYPE;
  running_total NUMBER := 0;
  max_score     CONSTANT scores.score%TYPE := 9;
  max_weight    CONSTANT performance_parts.weight%TYPE:= 1;
BEGIN
  SELECT s.score INTO n_score
  FROM SCORES s
  WHERE evaluation_id = s.evaluation_id
  AND performance_id = s.performance_id;

  SELECT p.weight INTO n_weight
  FROM PERFORMANCE_PARTS p
  WHERE performance_id = p.performance_id;

  BEGIN
    IF (n_weight > max_weight) OR (n_weight < 0) THEN
      RAISE weight_wrong;
    END IF;
  END;

  BEGIN
    IF (n_score > max_score) OR (n_score < 0) THEN
      RAISE score_wrong;
   END IF;
 END;

  running_total := n_score * n_weight;
  RETURN running_total;

EXCEPTION
  WHEN weight_wrong THEN
    DBMS_OUTPUT.PUT_LINE(
      'The weight of a score must be between 0 and ' || max_weight);
    RETURN -1;
  WHEN score_wrong THEN
    DBMS_OUTPUT.PUT_LINE(
      'The score must be between 0 and ' || max_score);
    RETURN -1;
END calculate_score;

Consulte también: Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre las excepciones definidas por el usuario