Когда я должен вложить МН / SQL НАЧИНАЮТ блоки КОНЦА …?

Я несколько случайно группировал подразделы кода в блоках BEGIN...END, когда он кажется правильным. Главным образом, когда я работаю над более длинной хранимой процедурой и существует потребность во временной переменной в одном месте, я объявлю это только для той части кода. Я также делаю это, когда я хочу определить и обработать исключения, выданные для определенной части кода.

Какие-либо другие причины, почему нужно вложить блоки в рамках процедуры, функции или другого большего блока МН / SQL?

14
задан OMG Ponies 25 February 2010 в 15:13
поделиться

3 ответа

Если вы хотите обрабатывать исключения локально следующим образом:

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; 
17
ответ дан 1 December 2019 в 13:33
поделиться

Я обычно вкладываю блоки, когда хочу создать процедуры, специфичные для данных, которые существуют только внутри блока. Вот надуманный пример:

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;

Конечно, обычно в этом нет необходимости, но он оказался в действительно удобным, когда процедура может быть вызвана из многих мест.

1
ответ дан 1 December 2019 в 13:33
поделиться

Одной из причин наличия вложенных блоков BEGIN / END является возможность обрабатывать исключения для определенного локального раздела кода и потенциально продолжать обработку, если исключение обработанный.

0
ответ дан 1 December 2019 в 13:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: