Приложения PL/SQL обычно строятся из пакетов, одни из которых относятся к API верхнего уровня, используемого программистами для реализации пользовательских требований, а другие решают вспомогательные задачи и предназначены для использования только другими пакетами.
До выхода Oracle Database 12c язык PL/SQL не мог помешать сеансу использовать любые подпрограммы пакетов, для которых схема данного сеанса обладает привилегией EXECUTE
.
В Oracle Database 12c все программные модули PL/SQL имеют необязательную секцию ACCESSIBLE BY
для определения «белого списка» модулей PL/SQL, которые могут обращаться к создаваемым или изменяемым модулям PL/SQL. Рассмотрим простой пример. Я начинаю с создания спецификации своего «общедоступного» пакета, который должен использоваться другими разработчиками для построения приложения:
CREATE OR REPLACE PACKAGE public_pkg
IS
PROCEDURE do_only_this;
END;
/
Затем я создаю спецификацию «приватного» пакета — «приватного» в том смысле, что он должен вызываться только из общедоступного пакета. Соответственно, я добавляю секцию accessible_by
:
CREATE OR REPLACE PACKAGE private_pkg
ACCESSIBLE BY (public_pkg)
IS
PROCEDURE do_this;
PROCEDURE do_that;
END;
/
Далее можно переходить к реализации тел пакетов. Процедура public_pkg.do_only_this
вызывает подпрограммы приватного пакета:
CREATE OR REPLACE PACKAGE BODY public_pkg
IS
PROCEDURE do_only_this
IS
BEGIN
private_pkg.do_this;
private_pkg.do_that;
END;
END;
/
CREATE OR REPLACE PACKAGE BODY private_pkg
IS
PROCEDURE do_this
IS
BEGIN
DBMS_OUTPUT.put_line ('THIS');
END;
PROCEDURE do_that
IS
BEGIN
DBMS_OUTPUT.put_line ('THAT');
END;
END;
/
Процедура общедоступного пакета запускается без малейших проблем:
BEGIN
public_pkg.do_only_this;
END;
/
THIS
THAT
Но при попытке вызвать подпрограмму приватного пакета в анонимном блоке я получу сообщение об ошибке:
BEGIN
private_pkg.do_this;
END;
/
ERROR at line 2:
ORA-06550: line 2, column 1:
PLS-00904: insufficient privilege to access object PRIVATE_PKG
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
Та же ошибка происходит при попытке откомпилировать программный модуль, пытающийся вызвать подпрограмму из приватного пакета:
SQL> CREATE OR REPLACE PROCEDURE use_private
2 IS
3 BEGIN
4 private_pkg.do_this;
5 END;
6 /
Warning: Procedure created with compilation errors.
SQL> sho err
Errors for PROCEDURE USE_PRIVATE:
LINE/COL ERROR
-------- ------------------------------------------------------------------
4/4 PL/SQL: Statement ignored
4/4 PLS-00904: insufficient privilege to access obj'ect PRIVATE_PKG
Как видно из текста сообщений, проблема обнаруживается во время компиляции. Использование данной возможности не приводит ни к каким отрицательным последствиям во время выполнения.