2010-02-25 12 views
14

Sono stato un po 'a casaccio raggruppare sottosezioni di codice in BEGIN ... END blocca quando sembra giusto. Principalmente quando sto lavorando su una stored procedure più lunga e c'è bisogno di una variabile temporanea in un punto, la dichiarerò solo per quella parte del codice. Lo faccio anche quando voglio identificare e gestire le eccezioni generate per una specifica porzione di codice.Quando dovrei annidare PL/SQL BEGIN ... END blocca?

Altri motivi per cui si devono annidare blocchi all'interno di una procedura, funzione o un altro blocco più grande di PL/SQL?

risposta

17

Quando si desidera gestire le eccezioni a livello locale in questo modo:

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 questo esempio, l'eccezione viene gestita e poi andiamo avanti ed elaborare il successivo dipendente.

Un altro utilizzo è quello di dichiarare le variabili locali che hanno limitato la portata in questo modo:

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; 

Intendiamoci, volendo fare questo è spesso un segno che il vostro programma è troppo grande e deve essere suddiviso:

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. Le best practice per i blocchi 'begin/end' sono blocchi anonimi, blocchi denominati (procedura/funzione) o per gestire eccezioni specifiche, come nel primo esempio. Annidare un'istruzione 'declare' all'interno di un blocco' begin/end' chiamerei un bug di programmazione, perché introduce la possibilità di collisioni con scope variabili, e quelle sono un problema di debug. –

1

Tendo a nidificare blocchi quando voglio creare procedure specifiche per i dati che esistono solo all'interno del blocco. Ecco un esempio inventato:

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; 

Certo, di solito non è necessario, ma è venuto a davvero utile quando una procedura può essere chiamato da molti luoghi.

+0

Non vedo l'esigenza: sei già all'interno di un ciclo. In secondo luogo, la dichiarazione della stored procedure non dovrebbe avvenire al di fuori del ciclo? –

+0

Ponticelli @OMG: lo scopo di questo esempio era di illustrare il fatto che è possibile dichiarare le procedure all'interno di un blocco per sfruttare i dati di quel blocco senza dover passare le informazioni tramite parametri. Hai ragione, se vuoi passare esplicitamente 'customer_id' come parametro a' create_invoice', dovrebbe essere dichiarato al di fuori del ciclo. Nella mia esperienza, mi sono imbattuto in situazioni in cui è più chiaro sfruttare le informazioni del blocco. –

0

Un motivo per cui i blocchi BEGIN/END nidificati devono essere in grado di gestire le eccezioni per una specifica sezione locale del codice e potenzialmente continuare l'elaborazione se l'eccezione viene elaborata.

Problemi correlati