Компиляция пакетов Oracle PL/SQL с помощью взаимозависимой процедуры
Если у меня есть процедура Proc1 и другая процедура Proc2, где proc1 зависит от proc2, а proc2 зависит от proc1 . Мне нужно скомпилировать пакет pkg1 с обеими этими процедурами.
Oracile 9i. Как мне этого добиться? какое-то конкретное ключевое слово требуется?
3 ответа
Я предполагаю, что это обе частные процедуры, то есть ни одна из них не указана в спецификации пакета.
Если бы обе процедуры появились в спецификации, проблем не было бы, потому что тело компилируется против публичного объявления.
Аналогично, если бы в процедуре появилась одна процедура, то снова не было бы проблемы: просто напишите частную процедуру в теле перед публичной процедурой.
Но если обе процедуры являются частными, то вам нужно использовать предварительное объявление. Это просто означает объявление подписей процедур в верхней части пакета. Точно так же, как положить их в спецификации, только частные. Вот спецификация...
create or replace package pkg as
procedure main (n0 in out number);
end;
/
... и тело...
create or replace package body pkg as
-- forward declarations
procedure p1 (n1 in out number);
procedure p2 (n2 in out number);
-- actual declarations
procedure p1 (n1 in out number)
is
begin
dbms_output.put_line('P1='||n1);
if n1 < 3 then
p2(n1);
end if;
end p1;
procedure p2 (n2 in out number)
is
begin
dbms_output.put_line('P2='||n2);
n2 := n2+1;
if n2 < 3 then
p1(n2);
end if;
end p2;
procedure main (n0 in out number)
is
begin
if n0 < 0 then
p1(n0);
else
p2(n0);
end if;
end main;
end pkg;
/
"Мне нужны взаимозависимые процедуры"
Вы действительно должны попытаться найти способ избежать циклических зависимостей. Это очень плохая практика программирования. Трудно понять, как эти процедуры взаимосвязаны, и мы должны управлять рекурсией и гарантировать, что обе процедуры обязательно завершатся в конечном итоге без вызова другой. Помните, что это не просто ваша проблема: это наследие, которое вы передадите одному из будущих разработчиков вашего кода.
Вы можете разорвать цепочку зависимостей, используя пакеты и скомпилировав все свои спецификации пакетов перед компиляцией тел пакетов. Все спецификации будут компилироваться независимо от зависимостей, и затем, когда тела будут скомпилированы, они могут делать это в любом порядке, поскольку будут ссылаться на уже скомпилированные спецификации. Как правило, спецификации пакетов хранятся с суффиксом *.pks, а тела с суффиксом *.pkb и какой-то сценарий сборки с их компиляцией. Вот так
/* Master Package Build Script */
-- Specs
@package_a.pks
@package_b.pks
@package_c.pks
-- Bodies
@package_a.pkb
@package_b.pkb
@package_c.pkb
Если обе процедуры указаны в спецификации, простая компиляция пакета должна работать:
alter package your_package compile;
Это предполагает, что ваш пакет действителен, конечно.
Если какая-либо (или обе) процедура не указана в спецификации, лучше всего перечислить ее как предварительное объявление в начале тела пакета.