· Функция, вызываемая из запроса SQL (SELECT), не может модифицировать таблицы базы данных. Т.е. команды INSERT, UPDATE, DELETE не допускаются
· Функция, вызываемая из DML утверждения, не может читать или изменять таблицы, модифицируемые этим утверждением
SQL> CREATE OR REPLACE PACKAGE comm_package
2 IS
3 FUNCTION avg_comm RETURN NUMBER;
4 END comm_package;
5 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY comm_package
2 IS
3 FUNCTION avg_comm
4 RETURN NUMBER
5 IS
6 l_comm NUMBER;
7 BEGIN
8 SELECT AVG(comm) INTO l_comm FROM emp;
9 RETURN l_comm;
10 END avg_comm;
11 END comm_package;
12 /
Package body created.
Пакетная функция avg_comm читает таблицу emp, чтобы вернуть среднее значение комиссионных. Эта функция может быть вызвана из запроса SQL, т.к. она не модифицирует таблицу emp, а только читает ее:
SQL> SELECT comm, comm_package.avg_comm FROM emp WHERE comm IS NOT NULL;
COMM AVG_COMM
--------- ---------
300 550
500 550
1400 550
0 550
Однако если мы попробуем использовать эту функцию для назначения комиссионных сотрудникам, для которых не определен комиссионный процент, возникнет ошибка, т.к. функция должна прочитать таблицу, которая в данный момент изменяется DML командой, вызвавшей функцию:
SQL> UPDATE emp SET comm=comm_package.avg_comm WHERE comm IS NULL;
UPDATE emp SET comm=comm_package.avg_comm WHERE comm IS NULL
*
ERROR at line 1:
ORA-04091: table EMP is mutating, trigger/function may not see it
ORA-06512: at "COMM_PACKAGE", line 8
ORA-06512: at line 1
Эта ошибка не была выявлена на этапе компиляция, а возникла только при выполнении функции. Чтобы указать компилятору на необходимость проверки пакетной функции на отсутствие «побочных эффектов», можно использовать директиву PRAGMA RESTRICT_REFERENCES в спецификации пакета. В директиве указывается уровень «чистоты» пакетной функции, тогда компилятор проверяет отсутствие соответствующих «побочных эффектов» при компиляции тела пакета и выдает ошибку компиляции, если тело функции нарушает эту директиву.
PRAGMA RESTRICT_REFERENCES (имя_функции, WNDS[, WNPS][, RNDS][, RNPS]);
имя_функции – имя функции, «чистоту» которой надо проверить
WNDS – функция не может изменять таблицы базы данных (Writes No Database State) – обязательный уровень «чистоты»
WNPS – функция не может изменять значения пакетных переменных (Writes No Package State)
RNDS – функция не может читать таблицы базы данных (Reads No Database State)
RNPS – функция не может ссылаться на пакетные переменные (Reads No Package State)
Директива PRAGMA RESTRICT_REFERENCES указывается в спецификации пакета, после объявления функции. «чистоту» которой она предписывает проверять.
Например, предполагая, что пакетная функция avg_comm будет использоваться для модификации таблицы, укажем директиву PRAGMA RESTRICT_REFERENCES в спецификации пакета comm_package, предписывающую проверять функцию, не читает ли она таблицы базы данных:
SQL> CREATE OR REPLACE PACKAGE comm_package
2 IS
3 FUNCTION avg_comm RETURN NUMBER;
4 PRAGMA RESTRICT_REFERENCES(avg_comm, WNDS, RNDS);
5 END comm_package;
6 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY comm_package
2 IS
3 FUNCTION avg_comm
4 RETURN NUMBER
5 IS
6 l_comm NUMBER;
7 BEGIN
8 SELECT AVG(comm) INTO l_comm FROM emp;
9 RETURN l_comm;
10 END avg_comm;
11 END comm_package;
12 /
Warning: Package Body created with compilation errors.
SQL> SHOW ERROR
Errors for PACKAGE BODY COMM_PACKAGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
3/4 PLS-00452: Subprogram 'AVG_COMM' violates its associated pragma
Ошибка, связанная с нарушением «чистоты от побочных эффектов», возникла на этапе компиляции тела пакета.
Для создания, выполнения, модификации и удаления пакетов требуются соответствующие системные и объектные привилегии.
Чтобы пользователь мог создавать пакеты в собственной схеме, необходима системная привилегия: Пакеты в собственной схеме можно перекомпилировать, выполнить или удалить, для этого привилегии не нужны.
· CREATE (ANY) PROCEDURE – право создавать хранимые программные единицы в собственной (или любой) схеме
· ALTER ANY PROCEDURE – право перекомпилировать программные единицы в любой схеме
· DROP ANY PROCEDURE – право удалять программные единицы в любой схеме
· EXECUTE ANY PROCEDURE – право выполнять любые программные единицы
Пользователь, создавший пакет, может предоставить кому-либо объектную привилегию на обращение к программным конструкциям этого пакета.
· EXECUTE имя_пакета
По умолчанию подпрограммы пакета выполняются с привилегиями пользователя, который его создал.
При компиляции спецификаций и тел пакетов исходный программный код, скомпилированные программы, статистические сведения и ошибки сохраняются в словаре данных, и информацию о них Вы можете получить через различные представления, колонка OBJECT_TYPE которых для спецификации пакета имеет значение PACKAGE, для тела – PACKAGE BODY:
Представление |
Описание |
USER_SOURCE |
Исходные тексты программ для всех хранимых программных модулей |
USER_ERRORS |
Список сообщений об ошибках компиляции по всем хранимым программным единицам |
USER_OBJECTS |
Общая информация о хранимых программных единицах в текущей схеме |
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.