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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2334659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 05:29:41  来源:igfitidea点击:

When should I nest PL/SQL BEGIN...END blocks?

sqloracleplsql

提问by aw crud

I've been somewhat haphazardly grouping subsections of code in BEGIN...END blocks when it seems right. Mostly when I'm working on a longer stored procedure and there's a need for a temporary variable in one spot I'll declare it just for that portion of the code. I also do this when I want to identify and handle exceptions thrown for a specific piece of code.

我在 BEGIN...END 块中有点随意地将代码的子部分分组,这似乎是正确的。大多数情况下,当我处理一个更长的存储过程并且需要在一个地方使用一个临时变量时,我将只为那部分代码声明它。当我想识别和处理为特定代码段抛出的异常时,我也会这样做。

Any other reasons why one should nest blocks within a procedure, function or another larger block of PL/SQL?

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

回答by Tony Andrews

When you want to handle exceptions locally like this:

当您想像这样在本地处理异常时:

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;

In this example, the exception is handled and then we carry on and process the next employee.

在这个例子中,异常被处理,然后我们继续处理下一个员工。

Another use is to declare local variables that have limited scope like this:

另一个用途是声明具有有限范围的局部变量,如下所示:

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;

Mind you, wanting to do this is often a sign that your program is too big and should be broken up:

请注意,想要这样做通常表明您的程序太大并且应该分解:

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; 

回答by Adam Paynter

I tend to nest blocks when I want to create procedures that are specific to data that only exists within the block. Here is a contrived example:

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

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;

Granted, it's not usually necessary, but it has come in reallyhandy when a procedure can be called from many locations.

诚然,这通常不是必需的,但是当可以从许多位置调用过程时,它确实派上了用场。

回答by dpbradley

One reason to have nested BEGIN/END blocks is to be able to handle exceptions for a specific local section of the code and potentially continue processing if the exception is processed.

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