Я несколько случайно группировал подразделы кода в блоках BEGIN...END, когда он кажется правильным. Главным образом, когда я работаю над более длинной хранимой процедурой и существует потребность во временной переменной в одном месте, я объявлю это только для той части кода. Я также делаю это, когда я хочу определить и обработать исключения, выданные для определенной части кода.
Какие-либо другие причины, почему нужно вложить блоки в рамках процедуры, функции или другого большего блока МН / SQL?
Если вы хотите обрабатывать исключения локально следующим образом:
begin
for emp_rec in (select * from emp) loop
begin
my_proc (emp_rec);
exception
when some_exception then
log_error('Failed to process employee '||emp_rec.empno);
end;
end loop;
end;
В этом примере обрабатывается исключение, а затем ведем и обрабатываем следующего сотрудника.
Другое использование - объявление локальных переменных с ограниченной областью действия, например:
declare
l_var1 integer;
-- lots of variables
begin
-- lots of lines of code
...
for emp_rec in (select * from emp) loop
declare
l_localvar integer := 0;
begin
-- Use l_localvar
...
end
end loop;
end;
Имейте в виду, что желание сделать это часто является признаком того, что ваша программа слишком велика и ее следует разбить:
declare
l_var1 integer;
-- lots of variables
...
procedure local_proc (emp_rec emp%rowtype):
l_localvar integer := 0;
begin
-- Use l_localvar
...
end
begin
-- lots of lines of code
...
for emp_rec in (select * from emp) loop
local_proc (emp_rec);
end loop;
end;
Я обычно вкладываю блоки, когда хочу создать процедуры, специфичные для данных, которые существуют только внутри блока. Вот надуманный пример:
BEGIN
FOR customer IN customers LOOP
DECLARE
PROCEDURE create_invoice(description VARCHAR2, amount NUMBER) IS
BEGIN
some_complicated_customer_package.create_invoice(
customer_id => customer.customer_id,
description => description,
amount => amount
);
END;
BEGIN
/* All three calls are being applied to the current customer,
even if we're not explicitly passing customer_id.
*/
create_invoice('Telephone bill', 150.00);
create_invoice('Internet bill', 550.75);
create_invoice('Television bill', 560.45);
END;
END LOOP;
END;
Конечно, обычно в этом нет необходимости, но он оказался в действительно удобным, когда процедура может быть вызвана из многих мест.
Одной из причин наличия вложенных блоков BEGIN / END является возможность обрабатывать исключения для определенного локального раздела кода и потенциально продолжать обработку, если исключение обработанный.