|
Программирование >> Oracle
Пакет DBMS UTILITY Пакет DBMS UTILITY - это набор процедур различного назначения. В него помещено несколько отдельных, не связанных между собой процедур. Пакет DBMS UTILITY стандартно устанавливается в базе данных, и привилегия EXECUTE для него предоставляется роли PUBLIC. Процедуры в этом пакете не взаимосвязаны, как в большинстве остальных пакетов. Например, все подпрограммы пакета UTL FILE имеют общее назначение - выполнение ввода-вывода в файл. Подпрограммы в пакете DBMS UTILITY практически независимы. Мы рассмотрим некоторые из этих подпрограмм, уделив особое внимание потенциальным проблемам при их использовании. Процедура COMPILE SCHEMA Процедура COMPILE SCHEMA предназначена для перекомпиляции недействительных (invalid) процедур, пакетов, триггеров, представлений, типов и других объектов схемы. Эта процедура работает в версии Oracle 8.1.6 на базе представления SYS.ORDER OBJECT BY DEPENDENCY. Представление возвращает объекты в порядке зависимостей. Начиная с версии Oracle 8.1.7, это представление больше не используется (почему, будет показано далее). Если компилировать объекты в порядке, задаваемом этим представлением, объекты, которые можно успешно перекомпилировать, окажутся действительными (valid). Эта процедура выполняет оператор ALTER COMPILE от имени пользователя, который вызвал процедуру COMPILE SCHEMA (т.е. она работает с правами вызывающего). Пакет DBMS UTILITY 1717 Процедура COMPILE SCHEMA требует передавать имена пользователей в верхнем регистре. Если вызвать: scott@TKYTE816> exec DBMS UTILITY.compile schema(scott); скорее всего, ничего не произойдет, если при создании учетной записи имя пользователя scott не задано в нижнем регистре (как идентификатор в кавычках - прим. научн.ред.). Необходимо передать имя схемы как SCOTT. При использовании процедуры COMPILE SCHEMA в версиях 8.1 сервера до 8.1.6.2 (т.е. во всех версиях 8.1.5, 8.1.6.0 и 8.1.6.1) возникает еще одна проблема. Если сервер поддерживает использование Java, в системе возникают рекурсивные зависимости. При вызове COMPILE SCHEMA выдается сообщение об ошибке: scott@TKYTE816> exec dbms utility.compile schema(user); BEGIN dbms utility.compile schema(user); END; at line 1: ORA-01436: CONNECT BY loop in user data ORA-06512: at SYS.DBMS UTILITY , line 195 ORA-06512: at line 1 Проблема связана с представлением SYS.ORDER OBJECT BY DEPENDENCY, поэтому в версиях, начиная с Oracle 8.1.7, оно не используется. Если вы столкнетесь с этим сообщением об ошибке, можно создать собственную процедуру COMPILE SCHEMA, работающую аналогично стандартной процедуре COMPILE SCHEMA. В этой процедуре можно компилировать объекты в любом порядке. Типичное заблуждение состоит как раз в том, что объекты надо компилировать в строго определенном порядке. На самом деле компилировать объекты можно в произвольном порядке и получить тот же результат, что и при компиляции в порядке, определяемом зависимостями. Алгоритм следующий: 1. Выбираем недействительный объект схемы, который мы еще не пытались перекомпилировать. 2. Компилируем его. 3. Возвращаемся к первому шагу, пока есть недействительные объекты, которые мы еще не пытались перекомпилировать. Определенного порядка придерживаться не обязательно. Причина - в побочном эффекте компиляции недействительного объекта. При этом все недействительные объекты, от которых он зависит, тоже будут скомпилированы. Надо только продолжать компилировать объекты, пока недействительных не останется. (На самом деле недействительные объекты могут остаться, но лишь потому, что скомпилировать их невозможно вообще.) Может оказаться, что при компиляции всего одной процедуры перекомпилированными окажутся 10 или 20 других объектов. Если не пытаться перекомпилировать эти 10 или 20 объектов вручную (при этом исходный объект снова станет недействительным), все будет в порядке. Поскольку реализация этой процедуры представляет определенный интерес, я продемонстрирую ее. Для выполнения оператора ALTER COMPILE необходимо исполь- 1718 Приложение А зовать процедуру с правами вызывающего. Необходим также доступ к представлению DBA OBJECTS для поиска следующего недействительного объекта и проверки состояния скомпилированного объекта. Не хотелось бы требовать обязательного доступа к представлению DBA OBJECTS от пользователя, выполняющего процедуру. Для этого придется использовать подпрограммы как с правами вызывающего, так и с правами создателя. Необходимо, однако, сделать так, чтобы вызываемая пользователем основная процедура работала с правами вызывающего, - это обеспечит использование ролей. Ниже представлена моя реализация процедуры COMPILE SCHEMA. Пользователь,выполняющий этот сценарий, должен получить привилегию SELECTHa представление SYS.DBA OBJECTS непосредственно (подробнее об этом можно прочитать в главе 23). Поскольку это сценарий для утилиты SQL*Plus, включающий ряд директив SQL*Plus, я представлю только сам сценарий, а не результаты его выполнения. Для указания имени схемы при компиляции объектов я использую подставляемую переменную SQL*Plus. Это делается потому, что процедура выполняется с правами вызывающего (и если необходимо всегда обращаться к одной и той же таблице, независимо от того, кто выполняет процедуру, имя таблицы необходимо уточнять), а я лично предпочитаю не полагаться на общедоступные синонимы. Я представлю сценарий по частям, комментируя каждую часть: column u new val uname select user u from dual; drop table compile schema tmp / create global temporary table compile schema tmp (object name varchar2(30) , object type varchar2(30) , constraint compile schema tmp pk primary key(object name,object type) on coit preserve rows / grant all on compile schema tmp to public / Сценарий начинается с получения имени текущего зарегистрировавшегося пользователя в подставляемую переменную SQL*Plus. Она будет использоваться в операторах CREATE OR REPLACE PROCEDURE. Это приходится делать, поскольку процедура должна выполняться с правами вызывающего и обращаться к созданной выше таблице. В главе 23 было описано, как разрешаются ссылки на таблицы с использованием стандартной схемы для пользователя, выполняющего процедуру. Используется одна временная таблица для всех сеансов, которая будет принадлежать пользователю, выполнившему этот сценарий. Поэтому необходимо явно указать имя пользователя в PL/SQL-процедуре. Временная таблица используется процедурами для запоминания
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |