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:
Publicar un comentario