Язык PL/SQL
требует, чтобы элементы были объявлены до того, как они будут использоваться в коде программы. Но как PL/SQL
определит, насколько корректно они применяются? Если одни модули вызывают другие, может возникнуть ситуация, когда невозможно объявить все модули до первой ссылки на них. Например, что делать, если программа А вызывает программу Б, а программа Б, в свою очередь, — программу А? К счастью, PL/SQL
поддерживает рекурсию, в том числе и взаимную, при которой две и более программ явно либо неявно вызывают друг друга.
Хорошая новость для программистов, использующих взаимную рекурсию: PL/SQL позволяет выполнять опережающее объявление локальных модулей, то есть объявлять модули до их фактической реализации. Это дает возможность вызывать модуль из других программ до его определения. Опережающее объявление состоит из заголовка программы, за которым следует точка с запятой. Эта конструкция называется заголовком модуля. Такой заголовок включает список параметров (и секцию RETURN
— для функций) и предоставляет всю информацию, которая необходима PL/SQL
для объявления модуля и правильной обработки любых обращений к нему.
В следующем примере внутри процедуры определяются две взаимно рекурсивные функции.
Следовательно, заголовок второй функции total_cost
должен определяться до объявления функции net_profit
:
PROCEDURE perform_calcs (year_in IN INTEGER)
IS
/* Только заголовок для функции total_cost. */
FUNCTION total_cost (...) RETURN NUMBER;
/* Функция net_profit использует total_cost. */
FUNCTION net_profit (...) RETURN NUMBER IS
BEGIN
RETURN total_sales (...) - total_cost (...);
END;
/* Функция total_cost использует net_profit. */
FUNCTION total_cost (...) RETURN NUMBER IS
BEGIN
IF <условие, основанное на параметрах>
THEN
RETURN net_profit (...) * .10;
ELSE
RETURN <значение параметра>;
END IF;
END;
BEGIN
END;
При использовании опережающих объявлений следует помнить некоторые правила:
- Программа не может содержать опережающие объявления переменных или курсоров. Этот прием работает только с модулями (процедурами или функциями).
- Определение программы должно содержаться в разделе объявлений того же блока PL/SQL (анонимного блока, процедуры, функции или тела пакета), в котором размещается опережающее объявление.
В одних случаях без опережающих объявлений не обойтись; в других они просто делают код более понятным и доступным. Опережающие объявления, как и все расширенные и нестандартные возможности PL/SQL, должны использоваться только тогда, когда они действительно необходимы.