Programmo Subito - 2 Livello -  Corso di  Visual Basic

Anche questo mese il corso dedicato a Visual Basic dà spazio ai database, con la trattazione di alcune clausole previste dal comando SQL SELECT

Corso di Visual Basic
Le query SQL

(parte XV)

di Maurizio Crespi

Continua la trattazione della gestione dei database in Visual Basic. Questo mese sono ancora protagoniste la query e in particolare alcune utili clausole previste dal comando SQL SELECT. Non mancherà, inoltre, un’occasione per rivedere i concetti esposti nelle ultime 10 lezioni di questo corso.

L’ordinamento dei dati risultanti dall’esecuzione di una query

Spesso si rivela opportuno fare in modo che i dati risultanti dall’esecuzione di una query siano presentati secondo un particolare ordine. Ad esempio, si supponga di disporre di un database contenente i dati anagrafici di tutti gli abitanti di un piccolo comune e di voler creare un’applicazione che permetta di estrarre l’elenco degli abitanti che nel corso del 1999 hanno compiuto o compieranno il diciottesimo anno di età. Si supponga che l’archivio preveda una tabella denominata Anagrafica, composta da record contenenti i campi Nome, Cognome, Indirizzo, AnnoNascita. Per estrarre dall’archivio tutti i nati nell’anno 1981 è necessaria una query descritta dalla seguente stringa SQL:

SELECT Nome, Cognome, Indirizzo
FROM Anagrafica
WHERE AnnoNascita=1981

Generalmente, quando si gestiscono delle anagrafiche, si tende ad agevolare l’utente presentando i nominativi in ordine alfabetico. La query descritta dalla stringa sopra menzionata non garantisce che ciò avvenga, in quanto non impone alcuna condizione in merito all’ordinamento dei dati.
Per fare in modo che essi siano presentati secondo un preciso ordine, è necessario introdurre una clausola aggiuntiva. La sintassi del comando SELECT diventa pertanto la seguente:

SELECT <elenco_campi>
FROM <nome_tabella>
[WHERE <condizione>]
[ORDER BY <ordinamento>]

dove <ordinamento> è descritto da

<ordinamento> = <campo 1> [, <campo 2>, ..., <campo n>]

Il primo campo indicato dopo la clausola ORDER BY è quello secondo il quale è effettuato il primo ordinamento dei dati. Qualora alcuni record prevedano valori analoghi all’interno dell’elemento specificato, essi sono ordinati fra loro in base al valore contenuto nel campo indicato dopo la virgola. In caso di ulteriore analogia fra alcuni record, essi sono ordinati fra loro in base al valore dell’eventuale terzo campo, ecc. Si noti che è obbligatorio indicare un nome di un campo dopo la clausola ORDER BY, mentre i successivi elementi sono facoltativi.
Per chiarire il concetto, si osservino gli esempi riportati di seguito. Si supponga di applicare la query descritta dalla stringa

SELECT Nome, Cognome
FROM Anagrafica
WHERE AnnoNascita=1981

al database contenente tutti gli abitanti di un piccolo comune.

Un possibile risultato è il seguente:

Rossi Marco
Bianchi Lucia
Rossi Alessandro
Verdi Marco
Rossi Davide
Gialli Claudia

Come si può notare, i dati non sono ordinati in base al contenuto dei campi.Si supponga ora di applicare allo stesso archivio la query:

SELECT Nome, Cognome
FROM Anagrafica
WHERE AnnoNascita=1981
ORDER BY Cognome

In questo caso, il risultato è il seguente:

Bianchi Lucia
Gialli Claudia
Rossi Davide
Rossi Marco
Rossi Alessandro
Verdi Marco

Ora i nominativi sono ordinati per cognome. Si noti però che è assente l’ordinamento per nome nel caso di individui caratterizzati dallo stesso cognome. Per sopperire a ciò è possibile applicare la seguente query:

SELECT Nome, Cognome
FROM Anagrafica
WHERE AnnoNascita=1981
ORDER BY Cognome, Nome

Questa volta, i dati sono presentati nel modo corretto:

Bianchi Lucia
Gialli Claudia
Rossi Alessandro
Rossi Davide
Rossi Marco
Verdi Marco

Ordinamento decrescente.

In mancanza di indicazioni contrarie, l’ordinamento avviene in modo crescente in base ai valori assunti dai campi indicati dopo la clausola ORDER BY. Si supponga ora di voler effettuare una query analoga alla precedente ma tale da fare in modo che l’ordinamento rispetto al campo Cognome sia decrescente. In questo caso, al nome del campo deve essere fatta seguire la parola DESC. Ad esempio, la stringa

SELECT Nome, Cognome
FROM Anagrafica
WHERE AnnoNascita=1981
ORDER BY Cognome DESC, Nome

fornisce il seguente risultato:

Verdi Marco
Rossi Alessandro
Rossi Davide
Rossi Marco
Gialli Claudia
Bianchi Lucia

Come si può notare, l’ordinamento è decrescente solo rispetto al campo dopo il cui nome è stata specificata la parola DESC, abbreviazione di descending. Per fare in modo che l’ordinamento sia decrescente anche nei confronti del campo Nome, è necessario quindi scrivere la seguente stringa SQL:

SELECT Nome, Cognome
FROM Anagrafica
WHERE AnnoNascita=1981
ORDER BY Cognome DESC, Nome DESC

Il risultato è costituito dalla sequenza:

Verdi Marco
Rossi Marco
Rossi Davide
Rossi Alessandro
Gialli Claudia
Bianchi Lucia

Query senza duplicati

Si supponga che per scopi statistici si debba produrre un elenco dei nomi di persona utilizzati nell’anno 1981 per iscrivere i nuovi nati all’anagrafe.

Ciò è possibile eseguendo sull’archivio la query descritta dalla stringa

SELECT Nome
FROM Anagrafe
WHERE AnnoNascita=1981
ORDER BY Nome

Il risultato è costituito dai seguenti valori:

Alessandro
Claudia
Davide
Lucia
Marco
Marco

Si noti che il nome "Marco" è duplicato. Infatti, come si è visto in precedenza, vi sono due individui omonimi. Nel caso dell’esempio, l’esistenza di un voce duplicata nel risultato rappresenta un fatto indesiderato. Per evitare che ciò avvenga, è possibile far uso della clausola DISTINCT. La sintassi del comando SQL SELECT diventa:

SELECT [DISTINCT] <elenco_campi>
FROM <nome_tabella>
[WHERE <condizione>]
[ORDER BY <ordinamento>]

La query da effettuare è quindi descritta dalla stringa:

SELECT DISTINCT Nome
FROM Anagrafe
WHERE AnnoNascita=1981
ORDER BY Nome

e il risultato è il seguente:

Alessandro
Claudia
Davide
Lucia
Marco

Un esempio

Il Listato 1 costituisce il codice sorgente di una semplice applicazione in grado di comporre ed eseguire una query SQL sul database descritto negli esempi precedenti. I file sono scaricabili da Internet all’indirizzo ftp://ftp.infomedia.it/pub/DEV./Listati. Il programma permette di selezionare, per mezzo di checkbox, i campi da visualizzare. Con l’ausilio di alcuni option button, inoltre, consente di stabilire i criteri di ricerca e di ordinamento. I risultati sono visualizzati in una listbox.
Si noti che l’oggetto di tipo Data è utilizzato solo per l’interfacciamento al database, non per la navigazione; lo stesso dicasi per le 3 label ad esso collegate. Per questo motivo, questi elementi sono stati resi invisibili.
Per realizzare questa applicazione è necessario disegnare un form dotato di tutti gli elementi necessari. Si provvede poi a collegare l’oggetto di tipo Data all’archivio e a legare ad esso le etichette testuali. A tal fine occorre inizializzare l’elemento di gestione del database utilizzando come proprietà RecordSource il nome della tabella da cui devono essere estratti i dati. Successivamente, dopo avere composto la query, il programma può provvedere a sostituire il contenuto della proprietà con la stringa in linguaggio SQL. Si noti che, dopo aver eseguito tale operazione, è necessario invocare il metodo Refresh per aggiornare l’oggetto di tipo Data e quindi per accedere al risultato dell’interrogazione. Si osservi altresì che, per verificare l’eventuale assenza di dati soddisfacenti le condizioni imposte, si fa uso della proprietà RecordCount, che indica il numero degli elementi presenti nel recordset (insieme di record) corrente.

Rinfreschiamoci la memoria…

Il corso dedicato a Visual Basic prosegue ormai da molto tempo e gli argomenti già trattati sono numerosi. Lo scopo di quest’ultima parte della lezione è di invitare il lettore a rivedere i temi discussi negli ultimi 10 numeri, sia per valutare il proprio livello di comprensione, sia per evitare che dei concetti importanti siano dimenticati in seguito all’acquisizione di nuove informazioni. Di seguito saranno quindi formulate alcune domande, a cui il lettore è invitato a rispondere. Le soluzioni corrette sono indicate di seguito in corsivo.

  • A cosa serve l’istruzione ReDim?
    L’istruzione ReDim permette di ridefinire un vettore per aumentare o ridurre la sua dimensione.
  • A quale fine a volte si specifica la clausola Preserve dopo l’istruzione ReDim?
    L’uso della clausola Preserve permette di aumentare la dimensione di un vettore senza perdere i valori in esso già contenuti.
  • L’indice iniziale di un vettore deve essere sempre 0?
    No, può essere qualsiasi valore intero.
  • Quali sono i principali vantaggi derivanti dall’uso delle subroutine?
    Le subroutine (o procedure) permettono di assegnare un nome a delle porzioni di codice usate in più punti di un programma. Esse possono poi essere richiamate semplicemente indicandone l’identificatore. Ciò rende più leggibile il codice dell’applicazione ed evita inutili duplicati al suo interno.
  • A cosa serve la parola chiave ByVal?
    La parola chiave ByVal permette di passare a una procedura un parametro per valore.
  • Quanti parametri possono essere passati a una procedura?
    Non esiste un limite ai parametri passabili a una procedura, sebbene non sia opportuno esagerare, onde evitare di produrre del codice scarsamente leggibile.
  • Che cosa differenzia un parametro passato per valore da uno passato per riferimento?
    Se si richiama una procedura passando come parametro una variabile, se esso è definito per riferimento si rende la procedura in grado di modificare il valore della variabile. Se invece il parametro è definito per valore, la procedura acquisisce il valore della variabile ma non la facoltà di modificarla.
  • Qual è la differenza che intercorre fra una funzione e una procedura?
    Una funzione può restituire dei valori. Una procedura invece no, a meno di ricorrere a dei parametri passati per riferimento.
  • Può una funzione restituire più di un valore?
    No, a meno che non si faccia uso di parametri passati per riferimento.
  • Quali rischi comporta un uso errato della ricorsione?
    Un uso errato della ricorsione, ad esempio quando non è specificata una condizione di uscita, può provocare il superamento della capacità massima dello stack di sistema (stack overflow).
  • Cos’è la procedura Main?
    La procedura Main, se presente, è la prima procedura eseguita all’avvio di un programma. Essa deve risiedere in un modulo (file di estensione BAS).
  • Qual è la differenza principale fra i file sequenziali e i file ad accesso casuale?
    I file ad accesso casuale permettono la ricerca delle informazioni senza comportare la lettura di tutto il proprio contenuto.
  • A cosa serve l’istruzione Open?
    Per mezzo dell’istruzione Open è possibile fare in modo che il programma assuma il controllo di un file per eseguire su di esso delle operazioni di lettura o scrittura.
  • A cosa serve la funzione Line Input?
    L’istruzione Line Input ha lo scopo di effettuare la lettura di una riga in un file di testo.
  • Cos’è un record?
    Un record è un agglomerato di informazioni di tipo non necessariamente omogeneo. Costituisce l’elemento fondamentale di cui sono composti i file ad acceso casuale.
  • Quando si apre un file ad accesso casuale, è opportuno specificare il parametro Len?
    E’ obbligatorio, al fine di consentire al sistema la distinzione dei record all’interno del file.
  • Qual è l’istruzione da utilizzare per leggere un record in un file ad accesso casuale?
    La lettura di un record in un file ad accesso casuale avviene per mezzo dell’istruzione Get.
  • Qual è l’istruzione che permette di scrivere un record in un file ad accesso casuale?
    La scrittura di un record in un file ad accesso casuale avviene per mezzo dell’istruzione Put.
  • Che vantaggi offre l’uso di un database in luogo di un file ad accesso casuale?
    L’uso di un database permette di gestire grandi quantità di dati in modo semplice, grazie all’uso di un "motore" in grado di eseguire autonomamente la maggior parte delle operazioni di ricerca e selezione.
  • Quali formati di database possono essere gestiti da Visual Basic?
    Visual Basic è in grado di gestire pressoché tutti i formati di database per i quali sia previsto un driver ODBC.
  • A cosa serve il metodo MoveFirst dell’oggetto Recordset?
    Il metodo MoveFirst permette di accedere al primo record presente in archivio.
  • Quando la proprietà EOF dell’oggetto Recordset assume il valore logico True?
    La proprietà EOF (End Of File) assume il valore True quando il programma giunge all’ultimo recrod presente in archivio.
  • Qual è la proprietà dell’oggetto Recordset che indica che la ricerca effettuata non è andata a buon fine?
    La proprietà che assume il valore logico True se un’operazione di ricerca non va a buon fine è denominata NoMatch.
  • Che vantaggi offre l’uso delle query?
    Le query permettono di fare in modo che il programma abbia una visione personalizzata dell’archivio, ovvero che acceda solo delle informazioni utili. Ciò semplifica il compito del programmatore, che non deve occuparsi dei filtrare i dati non necessari.
  • Qual è il linguaggio di definizione delle query supportato da Visual Basic?
    In Visual Basic le query sono descritte per mezzo del linguaggio SQL.
  • A cosa serve la clausola WHERE in una query SQL?
    La clausola WHERE permette di specificare la condizione che deve essere soddisfatta dai record che devono essere estratti dall’archivio.
  • Qual è la clausola da utilizzare per fare in modo che i dati siano ordinati in base al valore assunto da un campo?
    Per fare in modo che i dati siano ordinati in base al valore assunto da un campo è necessario far uso della clausola ORDER BY.
  • Com’è possibile far sì che l’ordinamento in funzione del valore assunto da un campo avvenga in modo decrescente?
    L’ordinamento avviene in modo decrescente se nella clausola ORDER BY accanto al nome del campo appare la parola DESC.
  • Com’è possibile fare in modo che l’esecuzione di una query su un archivio non produca record duplicati?
    Per evitare la generazione di record duplicati, è sufficiente far seguire la parola SELECT dalla clausola DISTINCT.

Bibliografia

"Visual Basic 5", McGrawHill, ISBN 88-386-0436-3

Note Biografiche

Maurizio Crespi si occupa di grafica, multimedialità, amministrazione di reti locali e geografiche, nonché della progettazione e dello sviluppo di applicazioni in C++, Visual Basic, Delphi e Director. Può essere contattato tramite Internet all’indirizzo mcrespi@infomedia.it.

VB-IT: per tutti gli sviluppatori VB o aspiranti tali

VB-IT e' la mailing list italiana interamente dedicata a Visual Basic, VBA (Visual Basic for Application) e VBScript. Se sei uno sviluppatore esperto oppure ti interessa il mondo Visual Basic anche solo per diletto, troverai VB-IT utilissima!
Consigli, suggerimenti, trucchi, soluzioni a problemi comuni e molto altro. Per iscriversi, gratuitamente, a VB-IT è sufficiente inviare un messaggio a majordomo@infomedia.it e nel body inserire la stringa: subscribe vb-it
Una volta iscritto, esponi i tuoi problemi a vb-it@infomedia.it e aiuta gli altri a risolvere i propri. Sarà anche un modo per instaurare nuovi rapporti di lavoro, collaborazione ed amicizia!