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

前端 未结 3 835
独厮守ぢ
独厮守ぢ 2020-12-28 18:41

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

相关标签:
3条回答
  • 2020-12-28 19:11

    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.

    0 讨论(0)
  • 2020-12-28 19:16

    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; 
    
    0 讨论(0)
  • 2020-12-28 19:30

    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 really handy when a procedure can be called from many locations.

    0 讨论(0)
提交回复
热议问题