Функция, объявленная в спецификации, является публичной и может быть вызвана извне пакета.Функция, которая определена в теле, но не объявлена в спецификации, является закрытой и может вызываться только из этого пакета.
В вашем примере вторая перегруженная версия вашей функции в теле пакета, которую вы 'он помечен как 'вторая функция', соответствует объявлению в спецификации, так что именно он задействуется при вызове функции из другого места:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
Первая перегруженная функция в вашем теле, которую вы 'Он помечен как «первая функция», в спецификации нет объявления соответствия, поэтому вы не можете вызывать его извне:
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
rc := jtestpkg.testfunc(42, in_out_1);
end;
/
ORA-06550: line 5, column 9:
PLS-00306: wrong number or types of arguments in call to 'TESTFUNC'
ORA-06550: line 5, column 3:
PL/SQL: Statement ignored
Мой вопрос в том, является ли «первая функция» втело пакета на самом деле вызывается
Нет.В вашем коде «первая функция» никогда не вызывается.
Она пытается вернуть себя.
Нет, это не так.Ваш 'first func' будет называть 'second func', если он сам был вызван откуда-то еще внутри пакета, но вы в настоящее время этого не делаете.
Отладка там говорит 'вызов первого функционала', но этоэто не так, он вызывает second func, поскольку вызываемый им вызов имеет три аргумента - в соответствии со списком аргументов 'second func'.(Это общедоступно, но это не имеет значения, если это не так, поскольку оно в любом случае является внутренним по отношению к пакету.)
В качестве примера, вы можете вызывать приватную функцию как часть создание и инициализация пакета :
...
END testfunc;
-- initialization, called on instantiation (for each session)
BEGIN
dbms_output.put_line('Initialization start');
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
dbms_output.put_line('Initialization: calling first func');
rc := testfunc(1, in_out_1);
end;
dbms_output.put_line('Initialization end');
END jtestpkg;
/
затем первый вызов в сеансе вызывает что-либо общедоступное в пакете, создает его экземпляр, который инициализирует его и запускает этот блок уровня пакета.Таким образом, с тем же анонимным блоком:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
вы видите (только в первый раз в сеансе):
Initialization start
Initialization: calling first func
invoking first func
FirstOUT_1SecondOUT_1
Initialization end
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
Вы по-прежнему видите тот же вывод FirstOUT_3SecondOUT_3
, что и раньше, иззначение 42 передано в этом вызове;но перед этим вы видите вывод FirstOUT_1SecondOUT_1
из 'first func', вызывающего 'second func' со значением 1, как часть этого процесса инициализации.
Разрешено для функции вызывать себя, т.е.рекурсивно, но ему нужно будет каждый раз менять вызов, иначе он застрянет в бесконечном цикле и в конечном итоге будет убит.Вы и здесь этого не делаете.