Когда мне следует вложить блоки PL / SQL BEGIN ... END? - PullRequest
14 голосов
/ 25 февраля 2010

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

Есть ли другие причины, по которым следует вкладывать блоки в процедуру, функцию или другой больший блок PL / SQL?

Ответы [ 3 ]

17 голосов
/ 25 февраля 2010

Когда вы хотите обрабатывать исключения локально, как это:

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; 
1 голос
/ 25 февраля 2010

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

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;

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

0 голосов
/ 25 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...