- •Виды хранимых процедур в Firebird
- •Пример выполнения практической работы
- •Некоторые дополнительные сведения Использование переменных
- •Управляющие конструкции begin..End
- •Процедуры с входными и выходными параметрами
- •Обработка данных в процедурах
- •Стандартные операторы
- •И еще примеры Процедуры без параметров
- •Процедуры с входными параметрами
- •Использование входных параметров и локальных переменных
- •Процедуры с выходными параметрами
- •Селективные процедуры
- •Вызов процедур из процедур или триггеров
- •Рекурсивные процедуры
- •Особенность вложенных вызовов процедур и рекурсивных процедур
- •Планы процедур и производительность Планы процедур
- •Производительность
- •Контрольные вопросы
Вызов процедур из процедур или триггеров
Ничего сложного, просто несколько правил
если процедура ничего не возвращает, то она так и вызывается: execute procedure proc (params);
если процедура возвращает один набор значений, то вызывается с опцией RETURNING_VALUES execute procedure proc (params) returning values (values);
если процедура селективная, то она вызывается точно так же, как и запросом для выборки данных select ... from proc
Пример: далее по тексту - рекурсивный вызов процедуры factorial.
Рекурсивные процедуры
CREATE PROCEDURE FACTORIAL (NUM INT)
RETURNS (N_FACTORIAL DOUBLE PRECISION)
AS
DECLARE VARIABLE NUM_LESS_ONE INT;
BEGIN
IF (NUM = 1) THEN
BEGIN /**** BASE CASE: 1 FACTORIAL IS 1 ****/
N_FACTORIAL = 1;
SUSPEND;
END
ELSE
BEGIN /**** RECURSION: NUM FACTORIAL = NUM * (NUM-1) FACTORIAL ****/
NUM_LESS_ONE = NUM - 1;
EXECUTE PROCEDURE FACTORIAL (NUM_LESS_ONE)
RETURNING_VALUES N_FACTORIAL;
N_FACTORIAL = N_FACTORIAL * NUM;
SUSPEND;
END
END;
В данном случае вычисление факториала – всего лишь пример.
Особенность вложенных вызовов процедур и рекурсивных процедур
Существует специфика работы с процедурами, которые вызываются из других процедур (или триггеров), а также рекурсивными. Обычно у процедуры можно легко поменять тип или количество параметров, однако после этого все процедуры и триггеры, вызывающие такую процедуру, перестанут работать, т.к. они ожидают при вызове этой процедуры другое количество параметров. Хуже того, backup базы данных с измененной таким образом процедурой пройдет, а вот restore - нет, т.к. в процессе restore производится проверка зависимостей метаданных (в т.ч. и процедур).
Поэтому, модифицировать вызываемые процедуры нужно следующим образом:
Допустим, у нас есть процедура A, у которой был параметр ID INT. И она вызывается из процедур B и C. Вы хотите добавить процедуре A дополнительный параметр, N VARCHAR(10).
вначале вызов процедуры (A), у которой вы планируете изменить параметры (количество и тип), нужно закомментировать во всех процедурах и триггерах, которые ее вызывают (B и C). обычно инструменты разработчика позволяют показывать зависимости, т.е. например какие процедуры зависят от изменяемой. Некоторые инструменты позволяют даже перекомпилировать зависимые процедуры или вообще все с автоматическим контролем изменяемых параметров.
затем вы меняете количество параметров у процедуры (A), и проверяете ее работоспособность (и меняя код с учетом изменения параметров) .
затем вы по очереди раскомментируете вызов процедуры (A) в вызывавших ее процедурах (B и C), проверяя их работоспособность (и меняя код с учетом изменения параметров)
примечание: изменение типа параметров, без изменения количества параметров, не обязательно сразу приведет к ошибкам при вызове такой процедуры из других процедур или триггеров. Все будет зависеть от конвертируемости данных между старым типом параметра и новым. То есть, три варианта - 1) ошибка есть сразу из-за неконвертируемости данных между типами; 2) ошибки нет, т.к. типы конвертируемые; 3) ошибка может возникнуть на определенных данных (буквы при varchar -> int).
примечание: быстро проверить, не возникнет-ли проблема с вызывающими процедурами после модификации процедур, можно сделав бэкап только метаданных (gbak -m ...) и затем их восстановление (restore). Этот процесс не делает резервное копирование данных, и таким образом намного быстрее.
