[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 596.   Linguaggio SQL: DML

DML, ovvero Data manipulation language, è il linguaggio usato per inserire, modificare e accedere ai dati. In questo capitolo viene trattato il linguaggio SQL per ciò che riguarda specificatamente l'inserimento, la lettura e la modifica del contenuto delle relazioni.

596.1   Inserimento, eliminazione e modifica dei dati

L'inserimento, l'eliminazione e la modifica dei dati di una relazione è un'operazione che interviene sempre a livello delle tuple. Infatti, come già definito, la tupla è l'elemento che costituisce l'unità di dati più piccola che può essere inserita o cancellata da una relazione.

596.1.1   Inserimento di tuple

L'inserimento di una nuova tupla all'interno di una relazione viene eseguito attraverso l'istruzione INSERT. Dal momento che nel modello di SQL gli attributi sono ordinati, è sufficiente indicare ordinatamente l'elenco dei valori della tupla da inserire, come mostra la sintassi seguente:

INSERT INTO nome_relazione VALUES (espressione_1[,...espressione_n])

Per esempio, l'inserimento di una tupla nella relazione Indirizzi già mostrata in precedenza, potrebbe avvenire nel modo seguente:

INSERT INTO Indirizzi
    VALUES (
        01,
        'Pallino',
        'Pinco',
        'Via Biglie 1',
        '0222,222222'
    )

Se i valori inseriti sono meno del numero degli attributi della relazione, i valori mancanti, in coda, ottengono quanto stabilito come valore predefinito, o NULL in sua mancanza (sempre che ciò sia concesso dai vincoli della relazione).

L'inserimento dei dati può avvenire in modo più chiaro e sicuro elencando prima i nomi degli attributi, in modo da evitare di dipendere dalla sequenza degli attributi memorizzata nella relazione. La sintassi seguente mostra il modo di ottenere questo.

INSERT INTO nome_relazione (attributo_1[,...attributo_n])]
    VALUES (espressione_1[,...espressione_n])

L'esempio già visto potrebbe essere tradotto nel modo seguente, più prolisso, ma anche più chiaro:

INSERT INTO Indirizzi (
        Codice,
        Cognome,
        Nome,
        Indirizzo,
        Telefono
    )
    VALUES (
        01,
        'Pallino',
        'Pinco',
        'Via Biglie 1',
        '0222,222222'
    )

Questo modo esplicito di fare riferimento agli attributi garantisce anche che eventuali modifiche di lieve entità nella struttura della relazione non debbano necessariamente riflettersi nei programmi. L'esempio seguente mostra l'inserimento di alcuni degli attributi della tupla, lasciando che gli altri ottengano l'assegnamento di un valore predefinito.

INSERT INTO Indirizzi (
        Codice,
        Cognome,
        Nome,
        Telefono
    )
    VALUES (
        01,
        'Pinco',
        'Pallino',
        '0222,222222'
    )

596.1.2   Aggiornamento delle tuple

La modifica delle tuple può avvenire attraverso una scansione della relazione, dalla prima all'ultima tupla, eventualmente controllando la modifica in base all'avverarsi di determinate condizioni. La sintassi per ottenere questo risultato, leggermente semplificata, è la seguente:

UPDATE relazione
    SET attributo_1=espressione_1[,...attributo_n=espressione_n]
    [WHERE condizione]

L'istruzione UPDATE esegue tutte le sostituzioni indicate dalle coppie attributo=espressione, per tutte le tuple in cui la condizione posta dopo la parola chiave WHERE si avvera. Se tale condizione manca, l'effetto delle modifiche si riflette su tutte le tuple della relazione.

L'esempio seguente aggiunge un attributo alla relazione degli indirizzi, per contenere il nome del comune di residenza; successivamente viene inserito il nome del comune «Sferopoli» in base al prefisso telefonico.

ALTER TABLE Indirizzi ADD COLUMN Comune char(30)
UPDATE Indirizzi
    SET Comune='Sferopoli'
    WHERE Telefono >= '022' AND Telefono < '023'

Eventualmente, al posto dell'espressione si può indicare la parola chiave DEFAULT che fa in modo di assegnare il valore predefinito per quel attributo.

596.1.3   Eliminazione di tuple

La cancellazione di tuple da una relazione è un'operazione molto semplice. Richiede solo l'indicazione del nome della relazione e la condizione in base alla quale le tuple devono essere cancellate.

DELETE FROM relazione [WHERE condizione]

Se la condizione non viene indicata, si cancellano tutte le tuple!

596.2   Interrogazioni di relazioni

L'interrogazione di una relazione è l'operazione con cui si ottengono i dati contenuti al suo interno, in base a dei criteri di filtro determinati. L'interrogazione consente anche di combinare assieme dati provenienti da relazioni differenti, in base a dei «collegamenti» che possono intercorrere tra queste.

596.2.1   Interrogazioni elementari

La forma più semplice di esprimere la sintassi necessaria a interrogare una sola relazione è quella espressa dallo schema seguente:

SELECT espress_col_1[,...espress_col_n]
    FROM relazione
    [WHERE condizione]

In questo modo è possibile definire gli attributi che si intendono utilizzare per il risultato, mentre le tuple si specificano, eventualmente, con la condizione posta dopo la parola chiave WHERE. L'esempio seguente mostra la proiezione degli attributi del cognome e nome della relazione di indirizzi già vista negli esempi delle altre sezioni, senza porre limiti alle tuple.

SELECT Cognome, Nome FROM Indirizzi

Quando si vuole ottenere una selezione composta dagli stessi attributi della relazione originale, nel suo stesso ordine, si può utilizzare un carattere jolly particolare, l'asterisco (*). Questo rappresenta l'elenco di tutti gli attributi della relazione indicata.

SELECT * FROM Indirizzi

È bene osservare che gli attributi si esprimono attraverso un'espressione, questo significa che gli attributi a cui si fa riferimento sono quelle del risultato finale, cioè della relazione che viene restituita come selezione o proiezione della relazione originale. L'esempio seguente emette un solo attributo contenente un ipotetico prezzo scontato del 10 %, in pratica viene moltiplicato il valore di un attributo contenente il prezzo per 0,90, in modo da ottenerne il 90 % (100 % meno lo sconto).

SELECT Prezzo * 0.90 FROM Listino

In questo senso si può comprendere l'utilità di assegnare esplicitamente un nome agli attributi del risultato finale, come indicato dalla sintassi seguente:

SELECT espress_col_1 AS nome_col_1][,...espress_col_n AS nome_col_n]
    FROM relazione
    [WHERE condizione]

In questo modo, l'esempio precedente può essere trasformato come segue, dando un nome all'attributo generato e chiarendone così il contenuto.

SELECT Prezzo * 0.90 AS Prezzo_Scontato FROM Listino

Finora è stata volutamente ignorata la condizione che controlla le tuple da selezionare. Anche se potrebbe essere evidente, è bene chiarire che la condizione posta dopo la parola chiave WHERE può fare riferimento solo ai dati originali della relazione da cui si attingono. Quindi, non è valida una condizione che utilizza un riferimento a un nome che appare dopo la parola chiave AS abbinata alle espressioni degli attributi.

Per qualche motivo che viene chiarito in seguito, può essere conveniente associare un alias alla relazione da cui estrarre i dati. Anche in questo caso si utilizza la parola chiave AS, come indicato dalla sintassi seguente:

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
    FROM relazione AS alias
    [WHERE condizione]

Quando si vuole fare riferimento al nome di un attributo, se per qualche motivo questo nome dovesse risultare ambiguo, si può aggiungere anteriormente il nome della relazione a cui appartiene, separandolo attraverso l'operatore punto (.). L'esempio seguente è la proiezione dei cognomi e dei nomi della solita relazione degli indirizzi. In questo caso, le espressioni degli attributi rappresentano solo gli attributi corrispondenti della relazione originaria, con l'aggiunta dell'indicazione esplicita del nome della relazione stessa.

SELECT Indirizzi.Cognome, Indirizzi.Nome FROM Indirizzi

A questo punto, se al nome della relazione viene abbinato un alias, si può esprimere la stessa cosa indicando il nome dell'alias al posto di quello della relazione, come nell'esempio seguente:

SELECT Ind.Cognome, Ind.Nome FROM Indirizzi AS Ind

596.2.2   Interrogazioni ordinate

Per ottenere un elenco ordinato in base a qualche criterio, si utilizza l'istruzione SELECT con l'indicazione di un'espressione in base alla quale effettuare l'ordinamento. Questa espressione è preceduta dalle parole chiave ORDER BY:

SELECT espress_col_1[,...espress_col_n]
    FROM relazione
    [WHERE condizione]
    ORDER BY espressione [ASC|DESC] [,...]

L'espressione può essere il nome di un attributo, oppure un'espressione che genera un risultato da uno o più attributi; l'aggiunta eventuale della parola chiave ASC, o DESC, permette di specificare un ordinamento crescente, o discendente. Come si vede, le espressioni di ordinamento possono essere più di una, separate con una virgola.

SELECT Cognome, Nome FROM Indirizzi ORDER BY Cognome

L'esempio mostra un'applicazione molto semplice del problema, in cui si ottiene un elenco dei soli attributi Cognome e Nome, della relazione Indirizzi, ordinato per Cognome.

SELECT Cognome, Nome FROM Indirizzi ORDER BY Cognome, Nome

Questo esempio, aggiunge l'indicazione del nome nella chiave di ordinamento, in modo che in presenza di cognomi uguali, la scelta venga fatta in base al nome.

SELECT Cognome, Nome FROM Indirizzi ORDER BY TRIM( Cognome ), TRIM( Nome )

Questo ultimo esempio mostra l'utilizzo di due espressioni come chiave di ordinamento. Per la precisione, la funzione TRIM(), usata in questo modo, serve a eliminare gli spazi iniziali e finali superflui. In questo modo, se i nomi e i cognomi sono stati inseriti con degli spazi iniziali, questi non vanno a influire sull'ordinamento.

596.2.3   Interrogazioni simultanee di più relazioni

Se dopo la parola chiave FROM si indicano più relazioni (ciò vale anche se si indica più volte la stessa relazione), si intende fare riferimento a una relazione generata dal prodotto di queste. Se per esempio si vogliono abbinare due relazioni, una di tre tuple con due attributi e un'altra di due tuple con due attributi, quello che si ottiene è una relazione con quattro attributi composta da sei tuple. Infatti, ogni tupla della prima relazione risulta abbinata con ogni tupla della seconda.

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
    FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
    [WHERE condizione]

Viene proposto un esempio banalizzato, con il quale poi si vuole eseguire un'elaborazione (figura 596.15).

Figura 596.15. Relazioni Articoli e Movimenti di una gestione del magazzino ipotetica.

relazione relazione

Da questa situazione si vuole ottenere la congiunzione della relazione Movimenti con tutte le informazioni corrispondenti della relazione Articoli, basando il riferimento sull'attributo Codice. In pratica si vuole ottenere la relazione della figura 596.16.

Tabella 596.16. Risultato del join che si intende ottenere tra la relazione Movimenti e la relazione Articoli.

relazione

Considerato che da un'istruzione SELECT contenente il riferimento a più relazioni si genera il prodotto tra queste, si pone poi il problema di eseguire una proiezione degli attributi desiderati e, soprattutto, di selezionare le tuple. In questo caso, la selezione deve essere basata sulla corrispondenza tra l'attributo Codice della prima relazione, con lo stesso attributo della seconda. Dovendo fare riferimento a due attributi di relazioni differenti, aventi però lo stesso nome, diviene indispensabile indicare i nomi degli attributi prefissandoli con i nomi delle relazioni rispettive.

SELECT
    Movimenti.Codice,
    Movimenti.Data,
    Movimenti.Carico,
    Movimenti.Scarico,
    Articoli.Descrizione
    FROM Movimenti, Articoli
    WHERE Movimenti.Codice = Articoli.Codice;

L'interrogazione simultanea di più relazioni si presta anche per elaborazioni della stessa relazione più volte. In tal caso, diventa obbligatorio l'uso degli alias. Si osservi il caso seguente:

SELECT Ind1.Cognome, Ind1.Nome
    FROM Indirizzi AS Ind1, Indirizzi AS Ind2
    WHERE
        Ind1.Cognome = Ind2.Cognome
    AND Ind1.Nome <> Ind2.Nome

Il senso di questa interrogazione, che utilizza la stessa relazione degli indirizzi per due volte con due alias differenti, è quello di ottenere l'elenco delle persone che hanno lo stesso cognome, avendo però un nome differente.

Esiste anche un'altra situazione in cui si ottiene l'interrogazione simultanea di più relazioni: l'unione. Si tratta semplicemente di attaccare il risultato di un'interrogazione su una relazione con quello di un'altra relazione, quando gli attributi finali appartengono allo stesso tipo di dati.

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
        FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
        [WHERE condizione]
    UNION
        SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
            FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
            [WHERE condizione]

Lo schema sintattico dovrebbe essere abbastanza esplicito: si uniscono due istruzioni SELECT in un risultato unico, attraverso la parola chiave UNION.

596.2.4   Condizioni

La condizione che esprime la selezione delle tuple può essere composta come si vuole, purché il risultato sia di tipo logico e i dati a cui si fa riferimento provengano dalle relazioni di partenza. Quindi si possono usare anche altri operatori di confronto, funzioni e operatori booleani.

È bene ricordare che il valore indefinito, rappresentato da NULL, è diverso da qualunque altro valore, compreso un altro valore indefinito. Per verificare che un valore sia o non sia indefinito, si deve usare l'operatore IS NULL oppure IS NOT NULL.

596.2.5   Aggregazioni

L'aggregazione è una forma di interrogazione attraverso cui si ottengono risultati riepilogativi del contenuto di una relazione, in forma di relazione contenente una sola tupla. Per questo si utilizzano delle funzioni speciali al posto dell'espressione che esprime gli attributi del risultato. Queste funzioni restituiscono un solo valore e come tali concorrono a creare un'unica tupla. Le funzioni di aggregazione sono: COUNT(), SUM(), MAX(), MIN(), AVG(). Per intendere il problema, si osservi l'esempio seguente:

SELECT COUNT(*) FROM Movimenti WHERE ...

In questo caso, quello che si ottiene è solo il numero di tuple della relazione Movimenti che soddisfano la condizione posta dopo la parola chiave WHERE (qui non è stata indicata). L'asterisco posto come parametro della funzione COUNT() rappresenta effettivamente l'elenco di tutti i nomi degli attributi della relazione Movimenti.

Quando si utilizzano funzioni di questo tipo, occorre considerare che l'elaborazione si riferisce alla relazione virtuale generata dopo la selezione posta da WHERE.

La funzione COUNT() può essere descritta attraverso la sintassi seguente:

COUNT( * )
COUNT( [DISTINCT|ALL] lista_attributi)

Utilizzando la forma già vista, quella dell'asterisco, si ottiene solo il numero delle tuple della relazione. L'opzione DISTINCT, seguita da una lista di nomi di attributi, fa in modo che vengano contate le tuple contenenti valori differenti per quel gruppo di attributi. L'opzione ALL è implicita quando non si usa DISTINCT e indica semplicemente di contare tutte le tuple.

Il conteggio delle tuple esclude in ogni caso quelle in cui il contenuto di tutti gli attributi selezionati è indefinito (NULL).

Le altre funzioni aggreganti non prevedono l'asterisco, perché fanno riferimento a un'espressione che genera un risultato per ogni tupla ottenuta dalla selezione.

SUM( [DISTINCT|ALL] espressione)
MAX( [DISTINCT|ALL] espressione)
MIN( [DISTINCT|ALL] espressione)
AVG( [DISTINCT|ALL] espressione)

In linea di massima, per tutti questi tipi di funzioni aggreganti, l'espressione deve generare un risultato numerico, sul quale calcolare la sommatoria, SUM(), il valore massimo, MAX(), il valore minimo, MIN(), la media, AVG().

L'esempio seguente calcola lo stipendio medio degli impiegati, ottenendo i dati da un'ipotetica relazione Emolumenti, limitandosi ad analizzare le tuple riferite a un certo settore.

SELECT AVG( Stipendio ) FROM Emolumenti
    WHERE Settore = 'Amministrazione'

L'esempio seguente è una variante in cui si estraggono rispettivamente lo stipendio massimo, medio e minimo.

SELECT MAX( Stipendio ), AVG( Stipendio ), MIN( Stipendio ) FROM Emolumenti
    WHERE Settore = 'Amministrazione'

L'esempio seguente è invece volutamente errato, perché si mescolano funzioni aggreganti assieme a espressioni di attributi normali.

-- Esempio errato
SELECT MAX( Stipendio ), Settore FROM Emolumenti
    WHERE Settore = 'Amministrazione'

596.2.6   Raggruppamenti

Le aggregazioni possono essere effettuate in riferimento a gruppi di tuple, distinguibili in base al contenuto di uno o più attributi. In questo tipo di interrogazione si può generare solo una relazione composta da tanti attributi quanti sono quelli presi in considerazione dall'opzione di raggruppamento, assieme ad altre contenenti solo espressioni di aggregazione.

Alla sintassi normale già vista nelle sezioni precedenti, si aggiunge la clausola GROUP BY.

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
    FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
    [WHERE condizione]
    GROUP BY attributo_1[,...]

Per comprendere l'effetto di questa sintassi, si deve scomporre idealmente l'operazione di selezione da quella di raggruppamento:

  1. la relazione ottenuta dall'istruzione SELECT...FROM viene filtrata dalla condizione WHERE;

  2. la relazione risultante viene riordinata in modo da raggruppare le tuple in cui i contenuti degli attributi elencati dopo l'opzione GROUP BY sono uguali;

  3. su questi gruppi di tuple vengono valutate le funzioni di aggregazione.

Figura 596.23. Carichi e scarichi in magazzino.

relazione

Si osservi la relazione riportata in figura 596.23, mostra la solita sequenza di carichi e scarichi di magazzino. Si potrebbe porre il problema di conoscere il totale dei carichi e degli scarichi per ogni articolo di magazzino. La richiesta può essere espressa con l'istruzione seguente:

SELECT Codice, SUM( Carico ), SUM( Scarico ) FROM Movimenti
    GROUP BY Codice

Quello che si ottiene appare nella figura 596.25.

Figura 596.25. Carichi e scarichi totali.

relazione

Volendo si possono fare i raggruppamenti in modo da avere i totali distinti anche in base al giorno, come nell'istruzione seguente:

SELECT Codice, Data, SUM( Carico ), SUM( Scarico ) FROM Movimenti
    GROUP BY Codice, Data

Come già affermato, la condizione posta dopo la parola chiave WHERE serve a filtrare inizialmente le tuple da considerare nel raggruppamento. Se quello che si vuole è filtrare ulteriormente il risultato di un raggruppamento, occorre usare la clausola HAVING.

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
    FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
    [WHERE condizione]
    GROUP BY attributo_1[,...]
    HAVING condizione

L'esempio seguente serve a ottenere il raggruppamento dei carichi e scarichi degli articoli, limitando però il risultato a quelli per i quali sia stata fatta una quantità di scarichi consistente (superiore a 1 000 unità).

SELECT Codice, SUM( Carico ), SUM( Scarico ) FROM Movimenti
    GROUP BY Codice
    HAVING SUM( Scarico ) > 1000

Dall'esempio già visto in figura 596.25 risulterebbe escluso l'articolo rond50.

596.3   Trasferimento di dati in un'altra relazione

Alcune forme particolari di interrogazioni SQL possono essere utilizzate per inserire dati in relazioni esistenti o per crearne di nuove.

596.3.1   Creazione di una nuova relazione a partire da altre

L'istruzione SELECT può servire per creare una nuova relazione a partire dai dati ottenuti dalla sua interrogazione.

SELECT specificazione_dell'attributo_1[,...specificazione_dell'attributo_n]
    INTO TABLE relazione_da_generare
    FROM specificazione_della_relazione_1[,...specificazione_della_relazione_n]
    [WHERE condizione]

L'esempio seguente crea la relazione Mia_prova come risultato della fusione delle relazioni Indirizzi e Presenze.

SELECT
    Presenze.Giorno,
    Presenze.Ingresso,
    Presenze.Uscita,
    Indirizzi.Cognome,
    Indirizzi.Nome
    INTO TABLE Mia_prova
    FROM Presenze, Indirizzi
    WHERE Presenze.Codice = Indirizzi.Codice;

596.3.2   Inserimento in una relazione esistente

L'inserimento di dati in una relazione esistente prelevando da dati contenuti in altre, può essere fatta attraverso l'istruzione INSERT sostituendo la clausola VALUES con un'interrogazione (SELECT).

INSERT INTO nome_relazione [(attributo_1...attributo_n)]
    SELECT espressione_1, ... espressione_n
        FROM relazioni_di_origine
        [WHERE condizione]

L'esempio seguente aggiunge alla relazione dello storico delle presenze le registrazioni vecchie che poi vengono cancellate.

INSERT INTO PresenzeStorico (
        PresenzeStorico.Codice,
        PresenzeStorico.Giorno,
        PresenzeStorico.Ingresso,
        PresenzeStorico.Uscita
    )
    SELECT
        Presenze.Codice,
        Presenze.Giorno,
        Presenze.Ingresso,
        Presenze.Uscita
        FROM Presenze
        WHERE Presenze.Giorno <= '01/01/1999';

DELETE FROM Presenze WHERE Giorno <= '01/01/1999';

596.4   Viste

Le viste sono delle relazioni virtuali ottenute a partire da relazioni vere e proprie o da altre viste, purché non si formino ricorsioni. Il concetto non dovrebbe risultare strano. In effetti, il risultato delle interrogazioni è sempre in forma di relazione. La vista crea una sorta di interrogazione permanente che acquista la personalità di una relazione normale.

CREATE VIEW nome_vista [(attributo_1[,...attributo_n)]]
    AS richiesta

Dopo la parola chiave AS deve essere indicato ciò che compone un'istruzione SELECT. L'esempio seguente, genera la vista dei movimenti di magazzino del solo articolo vite30.

CREATE VIEW Movimenti_Vite30
    AS SELECT Codice, Data, Carico, Scarico
        FROM Movimenti
        WHERE Codice = 'vite30'

L'eliminazione di una vista si ottiene con l'istruzione DROP VIEW, come illustrato dallo schema sintattico seguente:

DROP VIEW nome_vista

Volendo eliminare la vista Movimenti_Vite30, si può intervenire semplicemente come nell'esempio seguente:

DROP VIEW Movimenti_Vite30

596.5   Cursori

Quando il risultato di un'interrogazione SQL deve essere gestito all'interno di un programma, si pone un problema nel momento in cui ciò che si ottiene è composto da più di una sola tupla. Per poter scorrere un elenco ottenuto attraverso un'istruzione SELECT, tupla per tupla, si deve usare un cursore.

La dichiarazione e l'utilizzo di un cursore avviene all'interno di una transazione. Quando la transazione si chiude attraverso un'istruzione COMMIT o ROLLBACK, si chiude anche il cursore.

596.5.1   Dichiarazione e apertura

L'SQL prevede due fasi prima dell'utilizzo di un cursore: la dichiarazione e la sua apertura:

DECLARE cursore [INSENSITIVE] [SCROLL] CURSOR FOR
    SELECT ...
OPEN cursore

Nella dichiarazione, la parola chiave INSENSITIVE serve a stabilire che il risultato dell'interrogazione che si scandisce attraverso il cursore, non deve essere sensibile alle variazioni dei dati originali; la parola chiave SCROLL indica che è possibile estrarre più tuple simultaneamente attraverso il cursore.

DECLARE Mio_cursore CURSOR FOR
    SELECT
        Presenze.Giorno,
        Presenze.Ingresso,
        Presenze.Uscita,
        Indirizzi.Cognome,
        Indirizzi.Nome
        FROM Presenze, Indirizzi
        WHERE Presenze.Codice = Indirizzi.Codice;

L'esempio mostra la dichiarazione del cursore Mio_cursore, abbinato alla selezione degli attributi composti dal collegamento di due relazioni, Presenze e Indirizzi, dove le tuple devono avere lo stesso numero di codice. Per attivare questo cursore, lo si deve aprire come nell'esempio seguente:

OPEN Mio_cursore

596.5.2   Scansione

La scansione di un'interrogazione inserita in un cursore, avviene attraverso l'istruzione FETCH. Il suo scopo è quello di estrarre una tupla alla volta, in base a una posizione, relativa o assoluta.

FETCH [ [ NEXT | PRIOR | FIRST | LAST | { ABSOLUTE | RELATIVE } n ]
    FROM cursore ]
    INTO :variabile [,...]

Le parole chiave NEXT, PRIOR, FIRST, LAST, permettono rispettivamente di ottenere la tupla successiva, quella precedente, la prima e l'ultima. Le parole chiave ABSOLUTE e RELATIVE sono seguite da un numero, corrispondente alla scelta della tupla n-esima, rispetto all'inizio del gruppo per il quale è stato definito il cursore (ABSOLUTE), oppure della tupla n-esima rispetto all'ultima tupla estratta da un'istruzione FETCH precedente.

Le variabili indicate dopo la parola chiave INTO, che in particolare sono precedute da due punti (:), ricevono ordinatamente il contenuto dei vari attributi della tupla estratta. Naturalmente, le variabili in questione devono appartenere a un linguaggio di programmazione che incorpora l'SQL, dal momento che l'SQL stesso non fornisce questa possibilità.

FETCH NEXT FROM Mio_cursore

L'esempio mostra l'uso tipico di questa istruzione, dove si legge la tupla successiva (se non ne sono state lette fino a questo punto, si tratta della prima), dal cursore dichiarato e aperto precedentemente. L'esempio seguente è identico dal punto di vista funzionale.

FETCH RELATIVE 1 FROM Mio_cursore

I due esempi successivi sono equivalenti e servono a ottenere la tupla precedente.

FETCH PRIOR FROM Mio_cursore
FETCH RELATIVE -1 FROM Mio_cursore

596.5.3   Chiusura

Il cursore, al termine dell'utilizzo, deve essere chiuso:

CLOSE cursore

Seguendo gli esempi visti in precedenza, per chiudere il cursore Mio_cursore basta l'istruzione seguente:

CLOSE Mio_cursore

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome linguaggio_sql_dml.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico]

Valid ISO-HTML!

CSS validator!