back to top

Approfondimenti sui Cursori – Guida Oracle

Nel capitolo precedente abbiamo visto i cursori, più specificatamente abbiamo visto cosa sono e come si utilizzano i cursori espliciti. Esiste, tuttavia, un altro tipo di cursori, i cosiddetti cursori impliciti, che in realtà abbiamo già utilizzato pur senza saperlo. Infatti, ogni qualvolta eseguiamo un comando DML così come una query del tipo SELECT INTO, il server Oracle apre un cursore implicito. Tale tipo di cursore viene gestito automaticamente e, pertanto, non si devono usare i comandi OPEN, FETCH o CLOSE visti in precedenza per i cursori espliciti. Così come abbiamo visto accadere per i cursori espliciti, anche per i cursori impliciti Oracle mette a disposizione una serie di attributi per una migliore gestione:

  • SQL%ISOPEN – booleano, ritorna sempre FALSE in quanto chiude i cursori impliciti immediatamente dopo la loro esecuzione
  • SQL%FOUND – booleano, ritorna TRUE se l’ultimo comando SQL ha restituito delle righe
  • SQL%NOTFOUND – booleano, ritorna TRUE se l’ultimo comando SQL non ha restituito delle righe
  • SQL%ROWCOUNT – numerico, ritorna il numero totale di righe restituite dall’ultimo comando SQL
Per completezza vediamo di seguito come dovrebbe presentarsi il nostro blocco:
DECLARE
  Nome  varchar2(80);

BEGIN
  SELECT nome
  INTO   Nome
  FROM   anagrafica
  WHERE  cognome = 'ROSSI';

  IF SQL%NOTFOUND THEN
    INSERT INTO Log(messaggio)
    VALUES ('Nessuna ricorrenza.');
  END IF;

END;
In sostanza, se la nostra query non restituisce nessuna occorrenza, viene inserito un messaggio di errore nella nostra tabella Log.

Dopo questo breve accenno ai cursori impliciti, torniamo ancora sui cursori espliciti che stavamo trattando nel precedente capitolo. Abbiamo visto che, dopo aver definito un cursore, per gestirlo abbiamo bisogno di diversi comandi, ovvero abbiamo bisogno dei comandi OPEN, FETCH e CLOSE. Vedremo ora come, combinando l’utilizzo dei cursori con quello di un ciclo FOR, la gestione del cursore viene semplificata notevolmente. Avremo infatti che il ciclo FOR dichiara implicitamente un indice del loop come record %ROWTYPE avente la stessa struttura del cursore, apre il cursore, legge i valori e, infine, chiude il cursore quando sono state processate tutte le righe estratte. Vediamo come si presenterebbe il nostro blocco:

DECLARE
  ...;
  CURSOR cur_anagrafica IS
    SELECT nome, cognome, stipendio, ruolo
    FROM anagrafica;
  totale_stipendi NUMBER := 0;

BEGIN
  Istruzione1;
  FOR rec_anagrafica IN cur_anagrafica LOOP
    totale_stipendi := totale_stipendi + rec_anagrafica.stipendio;
  END LOOP;
END;
In pratica il ciclo FOR si occupa di tutte quelle incombenze cui generalmente dobbiamo pensare noi. Volendo, possiamo anche evitare di definire il cursore prima dell’ingresso nel LOOP specificando direttamente la query al posto del cursore. In tal caso il nostro blocco si presenterebbe così:
DECLARE
  ...;
  totale_stipendi NUMBER := 0;

BEGIN
  Istruzione1;
  FOR rec_anagrafica in (SELECT Nome, Cognome, Stipendio, Ruolo 
                         FROM Anagrafica;) LOOP
    totale_stipendi := totale_stipendi + rec_anagrafica.stipendio;
  END LOOP;
END;

PubblicitÃ