Panoramica sui cursori

Supponiamo di avere un database;
Possiamo accedere ai dati tramite una query del tipo:
SELECT […colonne…] FROM […tabelle…] WHERE […condizioni…];
Tuttavia, da un programma PL/SQL, non è sufficiente lanciare la query, c’è bisogno di memorizzare i dati da qualche parte per usarli.
Ci sono due alternative:
1) se il risultato della query è una singola riga si può usare una variabile con una sintassi di questo tipo:
SELECT […colonne …] INTO […variabili…] FROM […tabelle …] WHERE […condizioni …];
2) se il risultato della query consiste di più righe, c’è bisogno di usare un cursore.
Ci sono 2 tipi di cursore: espliciti ed impliciti.
————————————————————————————————————————
CURSORI ESPLICITI
La gestione dei cursori espliciti prevede quattro step:
1-DICHIARAZIONE
2-APERTURA*
3-FETCHING*
4-CHIUSURA*
1-dichiarazione
E’ necessario dichiarare il cursore nell’area dichiarativa del codice.
DECLARE
CURSOR cur_name IS
SELECT […colonne…]
FROM […tabelle…]
WHERE […condizioni…];
2-apertura
si esegue la query precedentemente dichiarata e si identifica il result type utilizzando lo statement OPEN
OPEN cur_name;
3-fetching
si recuperano i dati – una riga per volta – e si inserisce l’output della query in una o più variabili utilizzando lo statement FETCH;
per recuperare più righe bisogna inserire lo statement FETCH in un loop.
FETCH cur_name INTO […variabili…]
4-chiusura
si rilascia il cursore utilizzando lo statement CLOSE alla fine.
CLOSE cur_name;
*Attenzione:
gli statement di apertura, fetching e chiusura possono essere omessi usando il cursore in un ciclo FOR (vedere esempio #3).
————————————————————————————————————————
CURSORE IMPLICITO
Il cursore implicito è aperto da Oracle senza dichiarazione.
Avviene quando Oracle deve processare uno statement DML (per esempio, una query SQL)
Non possiamo usare gli statement OPEN, FETCH o CLOSE per questo tipo di cursore.
————————————————————————————————————————
ATTRIBUTI DEL CURSORE
per gestire i cursori espliciti si possono usare questi attributi:
%ISOPEN (boolean) è TRUE quando il cursore è aperto
%NOTFOUND (boolean) è TRUE quando FETCH non ritorna più righe
%FOUND (boolean) è TRUE fintanto che FETCH ritorna righe
%ROWCOUNT (numeric) numero di righe restituite fino ad ora
per gestire i cursori impliciti su possono usare questi attributi:
SQL%ISOPEN (boolean) è sempre FALSE perché i cursori impliciti vengono chiusi dopo l’esecuzione
SQL%FOUND (boolean) è TRUE se l’ultimo comando ha restituito righe
SQL%NOTFOUND (boolean) è TRUE se l’ultimo comando non ha restituito righe
SQL%ROWCOUNT (numeric) numero di righe restituite dall’ultimo comando
————————————————————————————————————————
ESEMPI DI CURSORE
esempio 1 – cursore esplicito, sintassi completa
DECLARE
var_firstname VARCHAR(20);
var_lastname VARCHAR(20);
var_salary people.salary%TYPE;
CURSOR cur_person IS
SELECT first_name, last_name, salary
FROM people;
BEGIN
OPEN cur_person;
LOOP
FETCH cur_person INTO var_firstname, var_lastname, var_salary;
EXIT WHEN cur_person%NOTFOUND;
/* …fa qualcosa… */
END LOOP;
CLOSE cur_person;
END;
/
esempio 2 – cursore esplicito, sintassi completa con record %ROWTYPE
DECLARE
CURSOR cur_person IS
SELECT first_name, last_name, salary
FROM people;
person_rec cur_person%ROWTYPE;
BEGIN
OPEN cur_person;
LOOP
FETCH cur_person INTO person_rec;
EXIT WHEN cur_person%NOTFOUND;
/* … fa qualcosa … */
END LOOP;
CLOSE cur_person;
END;
/
example 3 – cursore esplicito, ciclo FOR
DECLARE
total_sal people.salary%TYPE := 0;
CURSOR cur_person IS
SELECT first_name, last_name, salary
FROM people;
BEGIN
FOR single_person IN cur_person LOOP
total_sal := total_sal + single_person.salary;
END LOOP;
/* …fa qualcosa… */
DBMS_OUTPUT.PUT_LINE (‘amount: ‘ || total_sal);
END;
/
example 4 – cursore implicito
DECLARE
max_salary NUMBER(6) := 3000;
BEGIN
DELETE FROM people WHERE salary > max_salary;
DBMS_OUTPUT.PUT_LINE (‘Record deleted: ‘ || TO_CHAR(SQL%ROWCOUNT));
END;
/

Potrebbero interessarti anche...