Anuncios en tutorial de programación PLSQL

jueves, 9 de noviembre de 2017

Cláusula ACCESSIBLE BY (mejoras en la versión 12c de la base de datos Oracle)

La mayoría de la aplicaciones basadas en programas PL/SQL están constituidas por numerosos paquetes, algunos de los cuales son APIs de alto nivel que pueden ser utilizadas por los desarrolladores a la hora de implementar los requerimientos de los usuarios, y otros son paquetes de ayuda que son utilizados y llamados por otros paquetes dentro de la aplicación.

Versión 12c de la base de datos Oracle

Antes del reciente nacimiento de la versión 12c de las bases de datos Oracle, el código PL/SQL no podía restringir al esquema de una sesión el uso de aquellos subprogramas que se encontrasen en un paquete PLSQL para el que dicho esquema tuviese permisos de ejecución (GRANT EXECUTE). Con la llegada de la versión 12c de la base de datos Oracle, las unidades de programa PL/SQL pueden utilizar la nueva cláusula ACCESSIBLE BY que posibilita al desarrollador especificar un “lista blanca” de unidades PLSQL que tendrán acceso a la unidad PLSQL que está creando o modificando.

Echemos un vistazo al siguiente ejemplo para comprender mejor el funcionamiento de la cláusula ACCESSIBLE BY. Primero crearemos la especificación de un paquete PLSQL público que queremos que pueda ser utilizado por otros desarrolladores para programar sus propias aplicaciones.
CREATE OR REPLACE PACKAGE paquete_publico
IS PROCEDURE haz_solo_esto;
END;

El siguiente paso sería crear la especificación de nuestro propio paquete privado. Y decimos que el paquete es privado en el sentido de que queremos estar seguros de que va a poder ser invocado solo desde dentro del paquete publico definido anteriormente (paquete_publico). Para conseguirlo se utiliza la nueva cláusula ACCESIBLE BY:
CREATE OR REPLACE PACKAGE paquete_privado
ACCESSIBLE BY (paquete_publico)
IS
  PROCEDURE haz_esto;
  FUNCTION haz_aquello RETURN NUMBER;
END;
/

A continuación lo que se tiene que hacer es implementar el cuerpo de los paquetes. En el ejemplo el procedimiento paquete_publico.haz_solo_esto llama a los subprogramas de paquete_privado:
CREATE OR REPLACE PACKAGE BODY paquete_publico
IS
  PROCEDURE haz_solo_esto
  IS
    aquello NUMBER;
  BEGIN
    paquete_privado.haz_esto;
    aquello := paquete_privado.haz_aquello ();
    DBMS_OUTPUT.put_line (aquello);
  END;
END;
/

CREATE OR REPLACE PACKAGE BODY
paquete_privado
IS
  PROCEDURE haz_esto
  IS
  BEGIN
    DBMS_OUTPUT.put_line ('ESTO');
  END;

  FUNCTION haz_aquello RETURN NUMBER
  IS
  BEGIN
    DBMS_OUTPUT.put_line ('AQUELLO');
    RETURN 25;
  END;
END;
/

Ahora es posible ejecutar sin problemas el procedimiento del paquete público:
BEGIN
  paquete_publico.haz_solo_esto;
END;

Cuya salida por pantalla será:
ESTO
AQUELLO
25

Pero si intentamos llamar al subprograma en el paquete privado desde otro esquema diferente a aquel con el que creamos el paquete privado, entonces obtendremos el siguiente mensaje de error:
SQL>BEGIN
  2    paquete_privado.haz_esto;
  3  END;
  4  /
  paquete_privado.haz_esto;
  *
ERROR en línea 2:
ORA-06550: línea 2, columna 3:
PLS-00904: insuficientes privilegios para acceder
           al objeto 'PAQUETE_PRIVADO.HAZ_ESTO'
ORA-06550: línea 2, columna 3:
PL/SQL: Statement ignored

Y el mismo error ocurre si intentamos compilar con ese mismo esquema una unidad de programa que intenta llamar a un subprograma en el paquete privado:
SQL> CREATE OR REPLACE PROCEDURE
  2  usar_privado
  3  IS
  4  BEGIN
  5    paquete_privado.haz_esto;
  6  END;
  7  /

Advertencia: Procedimiento creado con 
             errores de compilación.

SQL> SHOW ERRORS
Errores para PROCEDURE USAR_PRIVADO:

LINE/COL ERROR
-------- ------------------------------------
5/3      PL/SQL: Statement ignored
5/3      PLS-00904: insuficientes privilegios
          para acceder al objeto 
         'PAQUETE_PRIVADO.HAZ_ESTO'

Por lo tanto, podemos ver que el error es capturado durante el tiempo de compilación, lo que quiere decir que utilizar esta nueva funcionalidad no afecta al rendimiento durante el tiempo de ejecución del procedimiento.

0 comentarios: