Ваш function_private
объявлен только в теле пакета, поэтому его область действия ограничена только другими процедурами в вашем пакете. Следовательно, он должен соответствовать уровню чистоты этих вызывающих процедур, иначе компилятор выдаст исключение.
Сравните это безопасное заявление (обратите внимание, я увеличил чистоту function_public
) ...
SQL> CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
2 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
3 PRAGMA RESTRICT_REFERENCES( function_public, WNDS, WNPS, RNDS);
4 END PRAGMA_TEST;
5 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
2 FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
3 BEGIN
4 return 'no harm done';
5 END;
6
7 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
8 BEGIN
9 return function_private(x);
10 END;
11 END PRAGMA_TEST;
12 /
Package body created.
SQL>
... с этим небезопасным ...
SQL> CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
2 FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
3 rv varchar2(1);
4 BEGIN
5 select dummy into rv from dual;
6 return rv;
7 END;
8
9 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
10 BEGIN
11 return function_private(x);
12 END;
13 END PRAGMA_TEST;
14 /
Warning: Package Body created with compilation errors.
SQL> sho err
Errors for PACKAGE BODY PRAGMA_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
9/3 PLS-00452: Subprogram 'FUNCTION_PUBLIC' violates its associated
pragma
SQL>
Смысл прагмы RESTRICTS_REFERENCES заключается в том, что процедуры, объявленные в спецификации пакета, могут использоваться другими пакетами, даже операторами SQL, принадлежащими или выполняемыми другими пользователями (схемами), которые могут не иметь доступа к источнику нашего тела пакета. Прагма - это метод, с помощью которого мы даем им заверения о влиянии включения нашего кода в их код. Вот почему прагма должна быть объявлена в спецификации, потому что это единственная часть кода, предоставляемая, когда мы предоставляем EXECUTE для пакета другому пользователю.
редактировать
Ах, теперь, увидев ваш исправленный пример кода, я понимаю, что вы пытаетесь сделать. Это не, не будет, не может работать. Нам разрешено использовать только упакованные функции, которые были объявлены в spec = public functions - в SQL. Не имеет значения, написан ли SQL в SQL * Plus или закодирован в другой упакованной процедуре. Причина, по которой в стеке ошибок совершенно ясно:
SQL> CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
2 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
3 PRAGMA RESTRICT_REFERENCES( function_public, WNDS, WNPS);
4 END PRAGMA_TEST;
5 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
2 FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
3 rv varchar2(1);
4 BEGIN
5 select dummy into rv from dual;
6 return rv;
7 END;
8
9 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
10 rv varchar2(1);
11 BEGIN
12 select function_private(x) into rv from dual;
13 return rv;
14 END;
15 END PRAGMA_TEST;
16 /
Warning: Package Body created with compilation errors.
SQL> sho err
Errors for PACKAGE BODY PRAGMA_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
12/6 PL/SQL: SQL Statement ignored
12/13 PL/SQL: ORA-00904: : invalid identifier
12/13 PLS-00231: function 'FUNCTION_PRIVATE' may not be used in SQL
SQL>
Компилятор отбрасывает ORA-00904: invalid identifier
, потому что функция не объявлена в спецификации; это не имеет никакого отношения к уровням чистоты,
примечание о сфере применения
PL / SQL не полностью состоит из его правил видимости : мы можем использовать частные переменные в нашем упакованном выражении SQL:
SQL> CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
2
3 gv constant varchar2(8) := 'global';
4
5 FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
6 rv varchar2(1);
7 BEGIN
8 select dummy into rv from dual;
9 return rv;
10 END;
11
12 FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
13 rv varchar2(10);
14 BEGIN
15 select gv||'+'||dummy into rv from dual;
16 return rv;
17 END;
18 END PRAGMA_TEST;
19 /
Package body created.
SQL>
Это просто функции и типы, которые wm должен объявить в спецификации, если мы хотим использовать их в операторах SQL.