web-dev-qa-db-ja.com

PL / SQL BEGIN ... ENDブロックはいつネストする必要がありますか?

私は、コードのサブセクションをBEGIN ... ENDブロックで、それが正しいと思われるときに、やや無計画にグループ化してきました。ほとんどの場合、より長いストアドプロシージャで作業していて、一時変数が1つの場所に必要な場合は、コードのその部分に対してのみ宣言します。また、特定のコードに対してスローされた例外を識別して処理する場合にもこれを行います。

プロシージャ、関数、またはPL/SQLの別のより大きなブロック内にブロックをネストする必要がある他の理由はありますか?

14
aw crud

次のようにローカルで例外を処理する場合:

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;

この例では、例外が処理されてから、次の従業員を続行して処理します。

もう1つの使用法は、次のようにスコープが制限されているローカル変数を宣言することです。

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
Tony Andrews

ブロック内にのみ存在するデータに固有のプロシージャを作成する場合、ブロックをネストする傾向があります。不自然な例を次に示します。

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
Adam Paynter

BEGIN/ENDブロックをネストする理由の1つは、コードの特定のローカルセクションの例外を処理し、例外が処理された場合に処理を続行できるようにするためです。

0
dpbradley