¿Qué es un contexto de aplicación?
El contexto de aplicación es simplemente un espacio en memoria que nos permite almacenar valores para luego utilizarlos en SQL o PL/SQL, como cualquier otra variable definida en el entorno. De forma transparente, mis objetos pueden ser 'manipulados' externamente sin necesidad que mis aplicaciones o procesos batch se enteren.
El contexto puede ser definido tanto localmente (privado para cada sesión) como globalmente, compartiendo sus valores para todas las sesiones de la instancia.
Para poder alterar los valores del contexto, debemos crear un paquete especialmente autorizado para ese fin. Esto es un requerimiento por razones de seguridad.
También necesitamos tener el permiso especial de sistema CREATE ANY CONTEXT.
Ejemplo (con sqlplus)
Vamos a ver un sencillo ejemplo de cómo implementar una vista parametrizada con contextos de aplicación, usando el popular usuario SCOTT. El parámetro para la vista en este caso será el número de departamento.
Paso 1: Crear el contexto de aplicación
CREATE CONTEXT app_ctx_scott USING pk_scott_app_contextPaso 2: Crear el paquete para manipular el contexto
/
CREATE OR REPLACE PACKAGE pk_scott_app_context ASPaso 3: Setear el parámetro de contexto deptno para el departamento de ventas
-- El contexto tendra un unico valor deptno
PROCEDURE set_dept (p_deptno IN NUMBER);
END;
/
CREATE OR REPLACE PACKAGE BODY pk_scott_app_context AS
PROCEDURE set_dept (p_deptno IN NUMBER) IS
BEGIN
DBMS_SESSION.SET_CONTEXT('app_ctx_scott', 'deptno', p_deptno);
END;
END;
/
BEGINPaso 4: Crear la vista parametrizada
pk_scott_app_context.set_dept(30);
END;
/
CREATE VIEW empleados ASPaso 5: Obtener los resultados consultando la vista
SELECT e.empno, e.ename, e.job, d.dname
FROM emp e, dept d
WHERE e.deptno=d.deptno
AND d.deptno = sys_context('app_ctx_scott','deptno');
SELECT * FROM empleados;Actualmente la vista retorna los empleados del departamento de ventas, ya que así está definida la variable en el contexto. Ahora cambiaré el valor del parámetro para que la vista retorne resultados únicamente del departamento contable:
EMPNO ENAME JOB DNAME
---------- ---------- --------- --------------
7499 ALLEN SALESMAN SALES
7521 WARD SALESMAN SALES
7654 MARTIN SALESMAN SALES
7698 BLAKE MANAGER SALES
7844 TURNER SALESMAN SALES
7900 JAMES CLERK SALES
6 rows selected.
BEGIN
pk_scott_app_context.set_dept(10);
END;
/
PL/SQL procedure successfully completed.
SELECT * FROM empleados;
EMPNO ENAME JOB DNAME
---------- ---------- --------- --------------
7782 CLARK MANAGER ACCOUNTING
7839 KING PRESIDENT ACCOUNTING
7934 MILLER CLERK ACCOUNTING
3 rows selected.
De la misma forma podemos aplicar esta técnica a procedimientos y funciones, pudiendo manipular valores utilizados internamente o inclusive introduciendo fragmentos de código como sql dinámico.

5 comentarios:
No entiendo por qué hace falta un contexto para utilizar una propiedad de un paquete en una vista.
¿Esto de los contextos tiene alguna otra utilidad?
Desde luego, los contextos son de vital importancia para poder implementar Fine-Grained Access Control para restringir el acceso a datos a nivel de filas (agregando dinámicamente filtros a las consultas que realiza un usuario), impidiendo que éste acceda a registros no autorizados dentro de un objeto. Basicamente defines políticas de seguridad (código que será incorporado a cada 'WHERE' de SQL). Luego esas políticas se asociarán a los usuarios, y Oracle automáticamente reescribirá los SELECTs que ejecute un usuario, para incorporar estos filtros. Para ese filtrado dinámico, Oracle hace uso del contexto definido.
Este es una funcionalidad muy interesante para seguridad de acceso a datos. En algún momento mostraré algun ejemplo práctico, igualmente la documentación al respecto en OTN es fácil de seguir.
Salvo que se me escape algo, si es necesario invocar explícitamente al setter no es nada que no se pueda hacer ya con un paquete convencional.
Supongo que cuando postees el ejemplo lo veré más claro.
En cualquier caso, gracias por compartirlo. Tienes un blog muy instructivo.
Gracias por los comentarios.
Las fine-grain policies no solamente permiten agregar este filtrado a vistas sino tambien a tablas. Con esto no afectamos bases de datos dependientes de otras aplicaciones, ya que no habrá necesidad de alterar ningún objeto. En ese sentido es 'transparente'. Además puedes idear lógica compleja con PL/SQL para armar el filtro dinámico.
Saludos
Me ha venido perfecto para parametrizar una vista, y tirar de ella tanto de una aplicación Java como desde Reports Builder.
Gracias¡¡
Publicar un comentario en la entrada