Il ciclo FOR in PL/SQL su Oracle 10g

lunedì 20 luglio 2009 alle 20:51 | Pubblicato su PL/SQL | 1 commento
Tag: , ,

Trovo solo ora il tempo e la forza per scrivere un nuovo post, per dare segni di vita su questo blog. Il contenuto non è molto avanzato, anzi mette in evidenza delle mie lacune della mia cultura PL/SQL (che però una alla volta cerco di colmare :) ).

Scrivendo un procedura PL/SQL la settimana scorsa, avendo la necessità di gestire un’eccezione all’interno di un ciclo FOR, avendo in questa gestione la necessità di registrare l’indice del ciclo che ha generato l’eccezione, ho scoperto che l’indice di un ciclo FOR in PL/SQL è una variabile locale al solo ciclo for, sempre.

Mi spiego meglio con un esempio:

SVILUPPO40@perseo10 > DECLARE
2   MY_EXCEPTION_IN_LOOP EXCEPTION;
3  BEGIN
4   FOR i IN 1..10 LOOP
5   IF i = 5 THEN
6     RAISE MY_EXCEPTION_IN_LOOP;
7   END IF;
8  END LOOP;
9  EXCEPTION
10  WHEN MY_EXCEPTION_IN_LOOP THEN
11  DBMS_OUTPUT.PUT_LINE(i);
12  END;
13  /
DBMS_OUTPUT.PUT_LINE(i);
*
ERRORE alla riga 11:
ORA-06550: riga 11, colonna 22:
PLS-00201: l’identificativo ‘I’ deve essere dichiarato
ORA-06550: riga 11, colonna 1:
PL/SQL: Statement ignored

Ora, io non so perché, immagino che in linguaggi come C e Java, i linguaggi con cui mi è capitato di lavorare in passato, l’indice o contatore del ciclo for debba essere una variabile esplicitamente dichiarata, io quando cominciai a scrivere i miei primi programmi in PL/SQL pensavo che la variabile contatore andasse dichiarata prima di poter essere utilizata. Poi ho scoperto che i programmi funzionavano anche se non mettevo tali dichiarazioni. Il fatto è che dietro questo meccanismo di nasconde una trappola, come mostro in questo esempio:

SVILUPPO40@perseo10 > DECLARE
2   MY_EXCEPTION_IN_LOOP EXCEPTION;
3   i NUMBER := -1;
4  BEGIN
5   FOR i IN 1..10 LOOP
6   IF i = 5 THEN
7     RAISE MY_EXCEPTION_IN_LOOP;
8   END IF;
9  END LOOP;
10  EXCEPTION
11  WHEN MY_EXCEPTION_IN_LOOP THEN
12  DBMS_OUTPUT.PUT_LINE(i);
13  END;
14  /
-1

Procedura PL/SQL completata correttamente.

Ovvero, quella che dichiaro e quella che viene usata nel ciclo for sono due variabili diverse, perché su due “livelli diversi”; quello che intendo è che io mi sarei aspettato, ingenuamente, nel caso sopra come output il valore 5. Invece occorre fare una cosa del genere:

SVILUPPO40@perseo10 > <<my_block>>
2  DECLARE
3   MY_EXCEPTION_IN_LOOP EXCEPTION;
4   i NUMBER := -1;
5  BEGIN
6   FOR i IN 1..10 LOOP
7   my_block.i := i;
8   IF i = 7 THEN
9     RAISE MY_EXCEPTION_IN_LOOP;
10   END IF;
11  END LOOP;
12  EXCEPTION
13  WHEN MY_EXCEPTION_IN_LOOP THEN
14  DBMS_OUTPUT.PUT_LINE(i);
15  END;
16  /
7

Procedura PL/SQL completata correttamente.

Qui ho voluto utilizzare un “feature” che non ho mai utilizzato, ovvero una “label, secondo me per evitare confusione è semplicemente meglio usare nomi di variabili diverse per non far confusione con le regole di “scoping”.

Rileggendo con attenzione questo paragrafo del manuale queste cose sono tutte ben spiegate, facile a dirsi, ma come titola il blog di Iggy Fernandez: “So Many Oracle Manuals, So Little Time”.

About these ads

1 commento »

RSS feed dei commenti a questo articolo. TrackBack URI

  1. Anche a me è capitato!
    Comunque Oracle documenta davvero tutto, ma non basterebbe un anno per leggere tutti i manuali….


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Blog su WordPress.com. | The Pool Theme.
Entries e commenti feeds.

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 71 follower

%d blogger cliccano Mi Piace per questo: