|
Программирование >> Oracle
Права вызывающего и создателя 1511 цедурных языках программирования), выполняется с привилегиями текущего зарегистрированного пользователя (вызывающего) и разрешением имен в его схеме. Теперь можно писать на PL/SQL код, который ранее приходилось писать на обычных языках программирования вне базы данных. Когда использовать права вызывающего В этом разделе мы рассмотрим различные причины и случаи, когда может потребоваться выполнение с правами вызывающего. Мы сконцентрируемся на правах вызывающего, поскольку это новая возможность, пока еще являющаяся исключением. Хранимые процедуры ранее всегда выполнялись сервером Oracle c правами создателя. Необходимость работать с правами вызывающего чаще всего возникает, когда универсальный фрагмент кода создается одним пользователем, а используется - множеством других. Разработчик не имеет доступа к объектам, к которым будут иметь доступ пользователи. Именно привилегии пользователя будут определять, к каким объектам этот код может обращаться. Другая потенциальная причина использования прав вызывающего - необходимость создать набор процедур, централизованно выбирающих данные из нескольких различных схем. При использовании процедур, работающих с правами создателя, как было показано, привилегии и схема, относительно которой выполняется разрешение имен, - статичны и определяются во время компиляции. При каждом выполнении процедура, работающая с правами создателя, обращается к одному и тому же набору объектов (если, конечно, не используется динамическое формирование SQL-операторов). Работа с правами вызывающего позволяет создать процедуру, способную обращаться к аналогичным структурам в различных схемах, - в зависимости от того, кто ее вызвал. Давайте рассмотрим ряд типичных случаев, когда используются процедуры с правами вызывающего. Разработка универсальных утилит Пусть создается хранимая процедура, использующая динамический SQL для выполнения запроса и вгдачи результатов в виде файла со значениями через запятую. Если не работать с правами вызывающего, эта процедура будет универсальной и полезной всем только при выполнении одного из следующих условий. Создатель процедуры должен иметь возможность читать любой объект в базе дан-н1х. Например, обладать привилегией SELECT ANY TABLE. B противном случае при запуске этой процедуры для представления данных таблицы в виде текстового файла произойдет ошибка, потому что создатель не имеет необходимой привилегии SELECT для этой таблицы. Надо выполнять эту процедуру с правами вызывающего, а не создателя. Каждый пользователь должен иметь исходный код и устанавливать его копию в своей схеме. Это нежелательно по очевидным причинам - сопровождение превратится в кошмар. Если будет обнаружена ошибка в исходном коде или вследствие обновления версии придется изменять код, обновлять придется десятки 1512 Глава 23 копий. Кроме того, эта скопированная процедура все равно не сможет обращаться к объектам, доступным пользователю через роль. Обычно именно второй вариант чаще всего применяется для разработки универсального кода. Этот подход неидеален, но более безопасен с точки зрения защиты данных. Используя работу с правами вызывающего, можно создать процедуру один раз, предоставить права на ее выполнение многим пользователям, и они будут использовать ее со своим набором привилегий и с разрешением имен в своих схемах. Давайте рассмотрим небольшой пример. Мне часто приходится просматривать в среде SQL*Plus слишком Широкие таблицы, имеющие много столбцов. Если просто выполнить SELECT * T для такой таблицы, утилита SQL*Plus будет переносить данные на следующую строку по правому краю окна терминала. Например: tkyte@DEV816> select * from dba tablespaces where rownum = 1; TABLESPAGE NAME INITIAL EXTENT NEXT EXTENT MIN EXTENTS MAX EXTENTS PGT INGREASE MIN EXTLEN STATUS GONTENTS LOGGING EXTENT MAN ALLOGATIO PLU SYSTEM 163 84 163 84 1 5 05 5 0 0 ONLINE PERMANENT LOGGING DIGTIONARY USER NO Полученные данные читать очень неудобно. Вот если бы получать результаты в следующем виде:
PL/SQL procedure successfully completed. Да, так гораздо лучше! Легко увидеть значение каждого столбца. Увидев резтат: использования моей процедуры PRINT TABLE, все хотят получить ее. Вместо того чтобы давать код, я предлагаю использовать мою, поскольку она создана с конструкцией AUTHID CURRENT USER. Мне не нужен доступ к чужим таблицам. Эта процедура сможет обращаться к ним (даже к тем, которые доступны через роль, - процедуры, Права в1зывающего и создателя 1513 работающие с правами создателя, не могут этого делать в принципе). Давайте рассмотрим код и разберемся, как он устроен. Начнем с создания служебной учетной записи для хранения этого универсального кода, а также учетной записи, которую мы будем использовать для проверки зашиты: tkyte@TKYTE816> grant connect to another user identified by another user; Grant succeeded. tkyte@TKYTE816> create user utils acct identified by utils acct; User created. tkyte@TKYTE816> grant create session, create procedure to utils acct; Grant succeeded. Я создал пользователя с очень ограниченными привилегиями. Их достаточно для того, чтобы зарегистрироваться и создать процедуру. Теперь я создам процедуру в этой схеме: tkyte@TKYTE816> utils acct/utils acct utils acct@TKYTE816> create or replace 2 procedure print table(p ery in varchar2) 3 AUTHID CURRENT USER 4 is 5 l theCursor integer default dbms sql.open cursor; 6 l columnValue varchar2(4000); 7 l status integer; 8 l descTbl dbms sql.desc tab; 9 l colCnt number; 10 begin 11 dbms sql.parse(l theCursor, p query, dbms sql.native); 12 dbms sql.describe columns(l theCursor, l colCnt, l descTbl); 14 for i in 1 .. l colCnt loop 15 dbms sql.define column(l theCursor, i, l columnValue, 4000); 16 end loop; 18 l status :=dbms sql.execute(l theCursor); 20 while (dbms sql.fetch rows(l theCursor) >0) loop 21 for i in 1 .. l colCnt loop 22 dbms sql.column value(l theCursor, i, l columnValue); 23 dbms output.put line(rpad(l descTbl(i).col name, 30) 25 l columnValue); 26 end loop; 27 dbms output.put line(- ) ; 28 end loop; 29 exception 30 when others then 31 dbms sql.dose cursor(l theCursor); 32 RAISE; 33 end;
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |