Программирование >>  Oracle 

1 ... 368 369 370 [ 371 ] 372 373 374 ... 469


Права вызывающего и создателя 1535

Устанавливается и поддерживается зависимость процедуры от объектов, на которые она ссылается. Если процедура выполняет оператор SELECT FROM T, регистрируется зависимость процедуры от таблицы Т.

Это означает, что подпрограмма с правами вызывающего при компиляции обрабатывается точно так же, как подпрограмма с правами создателя. Многих это сбивает с толку. Они слышали, что процедуры с правами вызывающего используют роли, и это так. Но (повторяю) они не используются в ходе компиляции. Это означает, что пользователь, компилирующий хранимую процедуру, ее владелец, должен иметь непосредствен-н1й доступ ко всем статически используемым таблицам. Вспомните пример из раздела Права создателя , где было показано, что можно успешно выполнить SELECT COUNT(*) FROM ЕМР в SQL и в анонимном блоке PL/SQL, но такой же оператор в хранимой процедуре приводит к ошибке компиляции. То же самое произойдет и в подпрограмме с правами вызывающего. Правила, сформулированные в разделе Privileges Requiredto CreateProceduresandFunctionsруководства Oracle 8iApplication DevelopersGuide остаются в силе: все равно необходим непосредственный доступ к базовым объектам.

Причина - в механизме зависимостей, используемом сервером Oracle. Если действие, выполняемое в базе данных (например, оператор REVOKE), делает процедуру с правами создателя недействительной, аналогичная процедура с правами вызывающего тоже становится недействительной. Различие между процедурами с правами вызывающего и создателя наблюдается только при выполнении. С точки зрения зависимостей, пометки процедур как недействительных и привилегий, необходимых владельцу процедуры, никаких различий нет.

Эту проблему можно обойти, и для большинства процедур с правами вызывающего проблема эта вообще не актуальна. Однако из-за нее иногда приходится создавать объекты-шаблоны. В следующем разделе мы рассмотрим, что такое объекты-шаблоны и как их использовать, чтобы избежать необходимости предоставления непосредственных привилегий.

Использование объектов-шаблонов

Теперь, зная, что при компиляции процедура с правами вызывающего не отличается от процедуры с правами создателя, можно понять, почему необходим непосредственный доступ ко всем объектам. При разработке процедур с правами вызывающего, в которых предполагается использование ролей, создателю необходимы непосредствен-н1е привилегии, а не роли. Их получение может оказаться невозможным по любой причине Достаточно, чтобы кто-то решил: Привилегии select на эту таблицу я не дам ), и придется искать решение.

Тут пригодятся объекты-шаблоны. Объект-шаблон - это объект, к которому пользователь-создатель имеет непосредственный доступ и по структуре совпадающий с объектом, к которому предполагается обращаться при выполнении. Его можно рассматривать как конструкцию struct языка С, Java-класс, PL/SQL-запись или структуру данных. Он создается для того, чтобы сервер знал количество и типы столбцов, и другие свойства объекта. Рассмотри это на примере. Предположим, необходимо создать процедуру, обращающуюся к представлению DBA USERS и выдающую в удобном формате оператор CREATE USER для любого существующего пользователя. Можно попытаться создать эту процедуру, например, так:



1536

Глава 23

tkyte@TKYTE816> create or replace

10 11 12 13 14 15 16 17 18 19 20 21

22 23

24 25

procedure show user info(p username in varchar2)

AUTHID GURRENT USER

l rec dba users%rowtype; begin

select *

into l rec

from dba users where username = upper(p username);

p username);

dbms output.put line(create user if (l rec.password = EXTERNAL) then

dbms output.put line( identified externally);

else

dbms output.put line ( identified by values l rec.password );

end if;

dbms output.put line

( temporary tablespace l rec.temporary tablespace default tablespace l rec.default tablespace profile l rec.profile); exception

when no data found then

dbms output.put line(*** Нет такого пользователя: II -> p username) ;

26 end;

27 /

Warning: Procedure created with compilation errors. tkyte@TKYTE816> show err

Errors for PROGEDURE SHOW USER INPO:

LINE/COL ERROR

SYS.DBA OSERS must be declared

must be declared

4/13 PLS-00201: identifier

4/13 PL/SQL: Item ignored

6/5 PL/SQL: SQL Statement ignored

8/12 PLS-00201: identifier SYS.DBA USERS

12/5 PL/SQL: Statement ignored

12/10 PLS-00320: the declaration of the type of this expression is incomplete or malformed

18/5 PL/SQL: Statement ignored 19/35 PLS-00320: the declaration incomplete or malformed

of the type of this expression is

Эта процедура не компилируется, не потому, что не существует объект SYS.DBA USERS, а потому, что обращаться к DBA USERS мы можем только благодаря предоставленной роли, а в ходе компиляции хранимой процедуры роли не используются. Так что же сделать, чтобы эта процедура скомпилировалась? Для этого можно создать собственную таблицу DBA USERS. Это позволит успешно скомпилировать процедуру. Однако no-



Права вызывающего и создателя

1537

скольку это не реальная таблица DBA USERS, желаемые результаты при выполнении не будут получены, пока мы не выполним процедуру от имени другого пользователя, который может обращаться к реальному представлению DBA USERS:

tkyte@TKYTE816> create table dba users

2 as

3 select * from SYS.dba users where 1=0; Table created.

tkyte@TKYTE816> alter procedure show user info compile; Procedure altered.

tkyte@TKYTE816> exec show user info(USER); *** Нет такого пользователя TKYTE

PL/SQL procedure successfully completed.

tkyte6TKYTE816>connect system/manager

system@TKYTE816> exec tkyte.show user info(TKYTE)

create user TKYTE

identified by values 698FlE51F530CA57

temporary tablespace TEMP default tablespace DATA profile DEFAULT PL/SQL procedure successfully completed.

Теперь мы получили процедуру, которая, при вызове любым пользователем, кроме создателя, обращается к правильному представлению DBA USERS (если вызывающий не имеет права обращаться к DBA USERS, он получит сообщение о том, что таблица или представление не существует). Если же процедуру выполняет создатель, он получает сообщение Нет такого пользователя , поскольку у него объект-шаблон DBA USERS пустой. Все остальные пользователи, однако, получают ожидаемые результаты. Во многих случаях это вполне приемлемо. Например, когда предполагается работа одного и того же кода с разными таблицами. В данном случае, однако, хотелось бы, чтобы эта процедура всегда работала с одним представлением, DBA USERS. Итак, возвращаемся к тому, как обеспечить работу этой процедуры для всех пользователей, включая создателя? Надо использовать объект-шаблон другого типа. Создадим таблицу, структурно совпадающую с представлением DBA USERS, но с другим именем, скажем, DBA USERS TEMPLATE. Используем эту таблицу для определения типа записи, в которую выбираются данные. После этого мы сможем динамически обращаться к представлению DBA USERS во всех случаях:

system@TKYTE816>connecttkyte/tkyte tkyte@TKYTE816>drop table dba users; Table dropped.

tkyte@TKYTE816> create table dba users TEMPLATE

2 as

3 select * from SYS.dba users where 1=0,-Tablecreated.

tkyte@TKYTE816>create or replace

2 procedure show user info(p username in varchar2)



1 ... 368 369 370 [ 371 ] 372 373 374 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика