• 1000 относятся к тем же элементам (Oracle V $ Views), но вы также поймете разницу между ролями, системными привилегиями и владением.
ТЕСТОВЫЙ СЛУЧАЙ
I создать тестового пользователя с именем test1
с некоторыми базовыми c привилегиями create procedure and create table
SQL> create user test1 identified by "Oracle_1" default tablespace tbtest temporary tablespace temp_group account unlock profile default quota unlimited on tbtest;
User created
SQL> grant create table, create procedure to test1;
Grant succeeded.
SQL> create table t ( c1 number , c2 number ) ;
Table created.
SQL> insert into t values ( 1 , 1 ) ;
1 row created.
Теперь я собираюсь создать процедуру и функцию, которые будут использовать v $ views. Для этого я предоставил test1 право выбора любой словарной системы.
SQL> create or replace procedure p
2 is
3 n integer;
4 begin
5 select count(*) into n from v$session where status = 'ACTIVE' ;
6* end;
/
Procedure created.
SQL> create or replace function f_get_count return number
is
n integer;
begin
select count(*)
INTO n
FROM v$mystat ms,
v$statname sn
WHERE ms.statistic# = sn.statistic#
AND sn.name = 'session pga memory' ;
return n;
end;
/
Function created
Итак, теперь у нас есть пользователь, который может получить доступ к v $ views, поскольку ему предоставлена системная привилегия SELECT ANY DICTIONARY, можем ли мы проверить, действительно ли все работает, как ожидалось.
SQL> show user
USER is "TEST1"
SQL> select count(*) from v$session ;
COUNT(*)
----------
62
SQL> select count(*) from v$mystat ;
COUNT(*)
----------
1804
SQL> select count(*) from v$statname ;
COUNT(*)
----------
1804
Теперь давайте попробуем вместо этого с процедурами.
SQL> select f_get_count from dual ;
F_GET_COUNT
-----------
1
SQL> exec p ;
PL/SQL procedure successfully completed.
В приведенном выше случае пользователь, который запускает процедуру, является владелец, поэтому он наследует выполнение своей собственной процедуры от предоставленной ему привилегии создания процедуры. Он также может успешно запустить процедуру и функцию, даже если они содержат v $ views, по той причине, что пользователю была предоставлена непосредственно системная привилегия выбора любого словаря.
Однако то же самое не работает с SELECT_CATALOG_ROLE.
SQL> grant select_catalog_role to test1 ;
Grant succeeded.
SQL> select f_get_count from dual ;
select f_get_count from dual
*
ERROR at line 1:
ORA-06575: Package or function F_GET_COUNT is in an invalid state
SQL> exec p ;
BEGIN p ; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object TEST1.P is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL> select count(*) from v$session ;
COUNT(*)
----------
63
Как видите, процедура и функция больше не работают, по сути, они стали НЕДЕЙСТВИТЕЛЬНЫМИ. Тем не менее, пользователь по-прежнему может видеть таблицы, поскольку эта привилегия была предоставлена SELECT_CATALOG_ROLE.
Если вы предоставите привилегию напрямую над v $ session, v $ mystat и v $ statname, все вернется к работе как и ожидалось.
SQL> grant select on v_$mystat to test1 ;
Grant succeeded.
SQL> grant select on v_$session to test1 ;
Grant succeeded.
SQL> grant select on v_$statname to test1 ;
Grant succeeded.
SQL> alter function f_get_count compile ;
Function altered.
SQL> alter procedure p compile ;
Procedure altered.
SQL> exec p;
PL/SQL procedure successfully completed.
SQL> select f_get_count from dual ;
F_GET_COUNT
-----------
1
Если владельцем процедуры является тот, кто ее выполняет, вы можете предоставить привилегию select any словарной системы, хотя я не рекомендую это делать. Предоставление этой привилегии всегда должно выполняться с особой осторожностью.
Попробуйте предоставить привилегии напрямую над реальными v $ представлениями. Лучшим сценарием является создание фиктивного пользователя / пользователя-контейнера, которому принадлежат привилегии и процедура, поэтому вам нужно только предоставить выполнение процедуры остальным пользователям.