Visitatori: 2425
Nella scorsa lezione abbiamo visto come dichiarare ed utilizzare un cursore esplicito. Abbiamo visto le operazioni di apertura, caricamento dati in memoria e chiusura del cursore (open, fetch e close), tuttavia la potenza di PL/SQL che è stato creato appositamente per superare i limiti di SQL, sta nel fatto che oltre ad accedere ai dati tramite i cursori possiamo anche effettuare operazioni di DELETE o UPDATE mentre scorriamo l'ACTIVE SET. Possiamo quindi valutare delle condizioni e in base al risultato aggiornare record o eliminarli.
Per effettuare operazioni di modiifca su un record caricato attraverso il comando FETCH si usa la clausola:
WHERE CURRENT OF
Tuttavia ciò non è sufficiente a consentirci di modificare i dati. Per fare ciò dobbiamo dichiarare esplicitamente che il nostro cursore viene creato per effettuare operazioni di modiifca dei dati. Facciamo ciò attraverso la clausola:
FOR UPDATE
Vediamo un esempio completo che chiarirà ogni dubbio.
DECLARE
nome VARCHAR(30);
cognome VARCHAR(30);
num_esami INT;
CURSOR studenti IS
SELECT nome_studente, cognome_studente, esami_sostenuti
FROM STUDENTI,
WHERE anno_corso=1
FOR UPDATE;
BEGIN
num_stud_promossi_2_anno := 0;
OPEN studenti;
Loop
FETCH studenti into nome, cognome, num_esami;
IF num_esami >= 5 THEN
num_stud_promossi_2_anno := num_stud_promossi_2_anno +1;
UPDATE STUDENTI SET anno_corso= 2 WHERE CURRENT OF studenti;
END IF;
End Loop
CLOSE studenti;
END;
L'Esempio è molto chiaro. Questa volta oltre a incrementare la nostra variabile num_stud_promossi_2_anno, andiamo ad aggiornare l'anno di corso (anno_corso) del nostro studente che ha superato più di 5 esami. Ciò possiamo farlo in quanto abbiamo dichiarato che il nostro cursore è destinato a operazioni di modiifca dei dati.
I CURSORI PL/SQL hanno degli attributi che ci consentono di gestire meglio i flussi.
%NOTFOUND: restituisce true se il cursore è arrivato alla fine, false altrimenti.
%FOUND: restituisce true se la fetch restituisce ancora un record (non sono arrivato alla fine), false altrimenti.
%ROWCOUNT: restituisce un intero che indica il numero di record estratti dal metodo FETCH al momento della chiamata.
%ISOPEN: restituisce true se il cursore è aperto, false altrimenti.
Per i primi 3 attributi occorre tuttavia fare una distinzione, ovvero considerare il caso in cui abbiamo fatto una SELECT e il caso in cui abbiamo effettuato operazioni di INSERT O UPDATE.
SELECT:
- viene restituita un record
- %FOUND vale TRUE
- %NOTFOUND vale FALSE
- %ROWCOUNT = 1;
- la select non restituisce nessun record
- %FOUND vale FALSE
- %NOTFOUND vale TRUE
- %ROWCOUNT = 0.
INSERT:
- viene effettuato 1 o più inserimenti
- %FOUND vale TRUE
- %NOTFOUND vale FALSE
- %ROWCOUNT = numero di righe inserite;
- nessun record viene inserito
- %FOUND vale FALSE
- %NOTFOUND vale TRUE
- %ROWCOUNT = 0.
UPDATE:
- viene aggiornato 1 o più record
- %FOUND vale TRUE
- %NOTFOUND vale FALSE
- %ROWCOUNT = numero di righe aggiornate;
- nessun record viene aggiornato
- %FOUND vale FALSE
- %NOTFOUND vale TRUE
- %ROWCOUNT = 0.
Utilizzando quindi gli attributi del nostro CURSORE possiamo far terminare il LOOP quando non viene restituito nessun record (siamo alla fine dell'ACTIVE SET).
DECLARE
nome VARCHAR(30);
cognome VARCHAR(30);
num_esami INT;
CURSOR studenti IS
SELECT nome_studente, cognome_studente, esami_sostenuti
FROM STUDENTI,
WHERE anno_corso=1
FOR UPDATE;
BEGIN
num_stud_promossi_2_anno := 0;
OPEN studenti;
Loop
FETCH studenti into nome, cognome, num_esami;
IF num_esami >= 5 THEN
num_stud_promossi_2_anno := num_stud_promossi_2_anno +1;
UPDATE STUDENTI SET anno_corso= 2 WHERE CURRENT OF studenti;
END IF;
EXIT WHEN studenti%NOTFOUND;
End Loop
CLOSE studenti;
END;
Nella prossima lezione vedremo l'utilizzo di un CURSORE FOR UPDATE che coinvolge più tabelle in join.
Lezione precedente | Indice degli articoli | Lezione successiva

|