|
Программирование >> Oracle
Права вызывающего и создателя 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)
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |