什么时候应该嵌套PL / SQL BEGIN ... END块?

时间:2010-02-25 14:30:29

标签: sql oracle plsql

当看起来正确的时候,我有点偶然地将BEGIN ... END块中的代码子组分组。大多数情况下,当我正在处理一个较长的存储过程并且在一个位置需要一个临时变量时,我将仅为该部分代码声明它。当我想识别和处理特定代码段抛出的异常时,我也会这样做。

为什么一个人应该在一个过程,函数或另一个更大的PL / SQL块中嵌套块?

3 个答案:

答案 0 :(得分:17)

如果您想在本地处理异常,请执行以下操作:

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 :(得分:1)

当我想创建特定于仅存在于块中的数据的过程时,我倾向于嵌套块。这是一个人为的例子:

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;

当然,它通常不是必需的,但是当从多个位置调用过程时,真的方便了。

答案 2 :(得分:0)

嵌套BEGIN / END块的一个原因是能够处理代码的特定本地部分的异常,并且如果处理异常则可能继续处理。