С учетом сказанного можно предложить более «правильный» (с точки зрения разработчиков Oracle) способ решения проблемы разграничения доступа к строкам:
CONNECT / AS SYSDBA
CREATE OR REPLACE CONTEXT dept_permissions USING permissions_package;
CREATE OR REPLACE PACKAGE permissions_package IS PROCEDURE set_location_context(loc IN VARCHAR2);
FUNCTION deptsallowed (obj_schema IN VARCHAR2, obj_name IN VARCHAR2)
RETURN VARCHAR2;
END permissions_package;
/
CREATE OR REPLACE PACKAGE BODY permissions_package IS
PROCEDURE set_location_context(loc IN VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT('dept_permissions', 'location', loc);
END;
FUNCTION deptsallowed (obj_schema IN VARCHAR2, obj_name IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN RETURN
'deptno in
(SELECT deptno
FROM scott.dept
WHERE loc = sys_context(''dept_permissions'', ''location''))';
END;
END permissions_package;
/
GRANT EXECUTE ON permissions_package TO scott;
EXECUTE DBMS_RLS.ADD_POLICY - ('scott','emp','epolicy','sys', - 'permissions_package.deptsallowed','select,update')
Проверка:
SQL> CONNECT scott/tiger
Connected.
SQL> EXECUTE -
> system.permissions_package.set_location_context('DALLAS')
SQL> SELECT SYS_CONTEXT('dept_permissions', 'location') FROM DUAL;
SYS_CONTEXT('DEPT_PERMISSIONS','LOCATION')
------------------------------------------
DALLAS
SQL> SELECT ename, loc FROM emp, dept WHERE emp.deptno = dept.deptno;
ENAME LOC ---------- ------------- SMITH DALLAS
JONES DALLAS
SCOTT DALLAS
ADAMS DALLAS
FORD DALLAS
5 rows selected.
Выглядит не самым простым образом, верно. Но зато возможностей при таком решении больше, чем при работе с непакетированной функцией-предикатом или же при использовании решения № 1. Так, меняя контекст сеанса мы приобретаем возможность регулировать объем выборки из одной и той же таблицы, не выполняя дополнительных подключений к БД.