Oracle

Manejo de errores en P/SQL

Por : Jhons_1101
2019-02-01
Tags :
Los errores de tiempo de ejecución se deben a errores de diseño, errores de codificación, fallos de hardware, y muchas otras fuentes. Aunque no se puede anticipar/preveer todos los errores posibles, lo que se puede hacer es planificar para darle manejo a ciertos tipos de errores significativos en su programa.

Al poder usar PL/SQL con multiples lenguajes de programación, debe existir compactibilidad para entregar la comprobación de errores, un error de tiempo de ejecución como el desbordamiento de pila o división por cero detiene el procesamiento normal y devuelverá un error. Un mecanismo para poder dar soporte es el llamado el manejo de excepciones le permite continuar operando en presencia de errores.

En PL/SQL, una condición de error se denomina excepción. Las excepciones se pueden definir internamente (por el sistema de tiempo de ejecución) o definidas por el usuario.

Se pueden definir excepciones de su propio en la parte declarativa de cualquier bloque PL/SQL, subprograma o paquete. Cuando se detiene la ejecución, el control se transfiere a la parte de control de excepciones de su bloque PL/SQL o subprograma. Para el caso de las excepciones internas son pasadas de manera implícita (automáticamente) por el sistema en tiempo de ejecución. En cambio las excepciones definidas por el usuario deben ser planteadas explícitamente por la expresión RAISE.
compartir en facebook compartir en Google compartir en Twitter compartir en Blogger compartir como código embebido compartir la url
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.

Recomendación en el uso de excepciones PL/SQL

Para estos casos, es recomendable hacer uso de las excepciones de PL/SQL, importante siempre definir un nombre o establecer el código del error no repetitivo para los raise_application_error.

  • Agregar control de excepciones cada vez que exista alguna posibilidad de que se produzca un error. Los errores son especialmente probables durante los cálculos aritméticos, la manipulación de cadenas, y las operaciones de base de datos.
  • Si se obtienen los datos de entrada. Si su código recibe parámetros incorrectos o nulos, que las consultas volverán ninguna fila o más filas de lo esperado.
  • Testear el código fuente (test QA) con diferentes combinaciones de datos malos datos que se espere fallen, con el fín de ver qué surgen errores potenciales y/o no esperados.
  • Cada vez que se genere un error. Guardelo.!!. Esto cone l fin de hacer la traza y poder depurar eventualmente errores. Se puede hacer con un Trigger ('cómo lo vimos en el tema anterior') o con PRAGMA AUTONOMOUS_TRANSACTION, para que pueda respaldar su información de depuración, sin irrumpir en el trabajo principal de su bloque PL/SQL o subpregrama.
  • Genere un listado de posibles errores de su aplicación. Con el fin de facilitar la depuración en caso de errores.


  • Sintáxis....

    
    DECLARE
        -- Parte declarativa
    BEGIN
        -- Parte de ejecución
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            -- Se ejecuta cuando ocurre una excepción de tipo NO_DATA_FOUND
        WHEN ZERO_DIVIDE THEN
            -- Se ejecuta cuando ocurre una excepción de tipo ZERO_DIVIDE
        WHEN OTHERS THEN
            -- Se ejecuta cuando ocurre una excepción no tratado o esperada
    END;
    
    

    Como se ha indicado, 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 continúa ejecutando el bloque anterior. Si existe un bloque de excepción apropiado para el tipo de excepción se ejecuta dicho bloque. Si no existe un bloque de control de excepciones adecuado al tipo de excepción se ejecutará el bloque de excepción WHEN OTHERS THEN (¡si existe!). WHEN OTHERS debe ser el último manejador de excepciones.


    Excepciones definidas de forma interna

    Las excepciones pueden ser definidas de forma interna o explícitamente por el usuario. Las excepciones definidas de 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. De igual manera existe un listado significativo, Aqui podemos ver con cual de ellas contamos..


    Excepción Error ORA SQLCODE Descripción
    ACCESS_INTO_NULL 06530 -6530 Un programa intenta asignar valores a los atributos de un objeto no inicializado
    CASE_NOT_FOUND 06592 -6592 Ninguna de las opciones en las cláusulas WHEN en un CASE se selecciona, y no hay ninguna cláusula ELSE.
    COLLECTION_IS_NULL 06531 -6531 Un programa intenta aplicar métodos de recogida de distintos EXISTS a una tabla anidada no inicializado o VARRAY, o el programa intenta asignar valores a los elementos de una tabla anidada no inicializado o VARRAY.
    CURSOR_ALREADY_OPEN 06511 -6511 Un programa intenta abrir un cursor que ya está abierto. Un cursor debe estar cerrado antes de que pueda volver a abrirse. Un cursor de bucle FOR se abre automáticamente el cursor al que se refiere, por lo que su programa no puede abrir ese cursor dentro del bucle.
    DUP_VAL_ON_INDEX 00001 -1 Un programa intenta almacenar valores duplicados en una columna que está limitada por un índice único.
    INVALID_CURSOR 01001 -11001 Un programa intenta una operación de cursor que no está permitido, como el cierre de un cursor sin abrir.
    INVALID_NUMBER 01722 -1722 la conversión de una cadena de caracteres en una serie falla porque la cadena no representa un número válido. (En las declaraciones de procedimiento, VALUE_ERROR se levantó.) Esta excepción también se produce cuando la expresión de la cláusula LIMIT en una declaración FETCH masiva no se evalúa como un número positivo.
    LOGIN_DENIED 01017 -1017 Un programa intenta iniciar sesión en Oracle con un nombre de usuario o contraseña no válidos.
    NO_DATA_FOUND 01403 +100 Una instrucción SELECT INTO no devuelve ninguna fila, o su programa hace referencia a un elemento de borrado de una tabla anidada o un elemento no inicializado en una tabla de índice-by. Debido a que esta excepción es utilizado internamente por algunas funciones SQL para indicar la finalización, no se debe confiar en esta excepción se propague si se eleva dentro de una función que se llama como parte de una consulta.
    NOT_LOGGED_ON 01012 -1012 Un programa emite una llamada de base de datos sin estar conectado a Oracle.
    PROGRAM_ERROR 06501 -6501 PL/SQL tiene un problema interno.
    ROWTYPE_MISMATCH 06504 -6504 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 30625 -30625 El parámetro SELF (el primero que es pasado a un método MEMBER) es nulo
    STORAGE_ERROR 06500 -6500 PL/SQL se queda sin memoria o está corrupta
    SUBSCRIPT_BEYOND_COUNT 06533 -6533 El programa está tratando de referenciar un elemento de una colección indexada que se encuentra en una posición más grande que el número real de elementos de la colección.
    SUBSCRIPT_OUTSIDE_LIMIT 06532 -6532 El programa está referenciando un elemento de una tabla utilizando un número fuera del rango permitido (por ejemplo, el elemento “-1”)
    SYS_INVALID_ROWID 01410 -1410 La conversión de una cadena de caracteres hacia un tipo ROWID falló porque la cadena no representa un número.
    TIMEOUT_ON_RESOURCE 00051 -51 Se excedió el tiempo máximo de espera por un recurso en Oracle
    TOO_MANY_ROWS 01422 -1422 Una sentencia SELECT INTO devuelve más de una fila
    VALUE_ERROR 06502 -6502 Ocurrió un error aritmético, de conversión o truncamiento. Por ejemplo, sucede cuando se intenta introducir un valor muy grande dentro de una variable más pequeña
    ZERO_DIVIDE 01476 -1476 El programa intentó efectuar una división por cero
    AGRADECIMIENTOS:
    https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/errors.htm#i7014



    Excepciones definidas por el usuario

    Las excepciones definidas por el usuario deben ser declaradas y deben ser planteadas explícitamente por la declaración RAISE.
    Las excepciones pueden ser declaradas sólo en la parte declarativa de un bloque PL/SQL, subprograma o paquete. Se declara una excepción mediante la introducción de su nombre, seguido de la palabra clave EXCEPTION. En el siguiente ejemplo, se declara una excepción llamada VALOR_NEGATIVO:

    Las excepciones y las declaraciones de variables son similares. Pero recuerde, una excepción es una condición de error, no un elemento de datos. A diferencia de las variables, las excepciones no pueden aparecer en las instrucciones de asignación o sentencias SQL. Sin embargo, se aplican las mismas reglas de ámbito de variables y excepciones.

    
    DECLARE
     -- Declaramos una excepción identificada por VALOR_NEGATIVO
        VALOR_NEGATIVO EXCEPTION;
        valor NUMBER;
    BEGIN
      -- Ejecución valor := -1;
        IF valor < 0 THEN
            RAISE VALOR_NEGATIVO;
        END IF;
    EXCEPTION  -- Excepción
    WHEN VALOR_NEGATIVO THEN
        dbms_output.put_line('El valor no puede ser negativo');
    END;
    
    

    Una de las características más interesantes de la excepciones es su propagación. Cuando se lanza una excepción, el control se transfiere hasta la sección EXCEPTION del bloque donde se ha producido la excepción.
    Entonces se busca un manejador válido de la excepción (WHEN THEN, WHEN OTHERS THEN) dentro del bloque actual. En el caso de que no se encuentre ningún manejador válido, el control del programa se desplaza hasta el bloque EXCEPTION que ha realizado la llamada PL/SQL.

    Esto quiere decir que si tengo un bloque que llama a una excepcion, y esta no está declarada en el bloque, procedimiento o paquete.. El comportamiento, será el siguiente...


    El procedimiento RAISE_APPLICATION_ERROR le permite emitir mensajes de error ORA definidos por el usuario desde subprogramas almacenados de esta manera, se puede informar de errores en su aplicación y evitar volver excepciones no controladas.

    Para llamar RAISE_APPLICATION_ERROR, utilice la sintaxis.
        
        DECLARE
            raise_application_error(numero_de_error, message[, {TRUE | FALSE}]);
        
        
    Donde 'numero_de_error' es un número entero negativo en el rango -20000 -20999 .. y 'message' es una cadena de caracteres de hasta 2048 bytes de longitud. El tercer parámetro opcional, si es TRUE, se coloca el error en la pila de errores anteriores. Si el parámetro es FALSE (el valor predeterminado), el error sustituye a todos los errores anteriores.

    RAISE_APPLICATION_ERROR es parte del paquete DBMS_STANDARD, y cómo con el paquete STANDARD, no es necesario para calificar las referencias a ella. Una aplicación puede llamar RAISE_APPLICATION_ERROR sólo desde un subprograma almacenado (o método). Cuando se llama, RAISE_APPLICATION_ERROR termina el subprograma y devuelve un número de error definido por el usuario y el mensaje a la aplicación.

    El número de error y el mensaje pueden ser atrapados como cualquier error de Oracle.




    Redeclarando Excepciones predefinidas


    Recuerde, PL/SQL declara excepciones a nivel mundial en el paquete predefinido STANDARD, por lo que no los necesita declarar a sí mismo. Redeclarandolos excepciones predefinidas es propenso a errores debido a que su declaración local anula la declaración global.

    Por ejemplo, si se declara una excepción nombrada invalid_number a continuación, PL/SQL plantea la excepción predefinida INVALID_NUMBER internamente, un manejador escrito para INVALID_NUMBER no detecta la excepción interna. En tal casos, debe utilizar la notación de puntos para especificar la excepción predefinida, de la siguiente manera:
        
        DECLARE
            EXCEPTION
                WHEN invalid_number OR STANDARD.INVALID_NUMBER THEN
                -- handle the error
        END;
        
        







    Si este contenido te fue útil, no olvides compartirlo en redes sociales, Considéralo. Puede ser la manera de agradecer!


    Agrega tu comentario...

    Puedes utilizar etiquetas <pre></pre>, <p></p>, <div></div>, + (Nombre usuario, para responderle a alguien)

    nj7myp1





    Este post no tiene comentarios, sé el primero en hacerlo
    Esta entrada no cuenta con imágenes adjuntas

    Unete al grupo de whatsApp +57 316 392 6456

    Sigue el grupo en facebook

    Siguenos.....