Uso degli ADO in Visual Basic 6 di Nicola Pietralunga (Settima parte)
Presentiamo in queste pagine il tutorial relativo all'uso degli ADO in Visual Basic 6.0
scritto da Nicola Pietralunga l'8 Aprile 1999.
Chi volesse porre domande sull'argomento può rivolgersi direttamente all'Autore di cui riportiamo
l'indirizzo email: nicola@omeganet.it oppure inserire
un annuncio nella rubrica 'Chiedilo agli esperti'.
Come si legge dal comunicato dell'Autore, la riproduzione del testo e dei files che lo accompagnano
deve essere necessariamente preceduta dall'autorizzazione dello stesso, tranne naturalmente nel caso
di uso personale. |
Aprire il Recordset
Avendo a disposizione la Connection ora non manca che l’apertura del Recordset per la gestione dell’elenco dei Programmatori.
Il Recordset in ADO, come anche in DAO, rappresenta l’insieme di Record estratti da una tabella del DataBase oppure ottenuti per effetto di un comando (p.es. un’istruzione SELECT SQL).
Le proprietà fondamentali che ci interessano sono: CursorLocation, Source, ActiveConnection, CursorType e LockType.
La proprietà CursorLocation è analoga a quella già vista per l’oggetto Connection; nel caso non venga specificata utilizza di default quella della Connection. E’ necessario settare la proprietà sempre prima dell’apertura del Recordset.
Personalmente tendo ad utilizzare cursori lato Server quando ho bisogno di Recordset aggiornabili e quelli lato Client quando mi serve un Recordset in sola lettura (p.es. per popolare una Combobox o una Griglia senza che l’utente possa modificare quei dati). Quando bisogna popolare un controllo, infatti, i dati servono comunque tutti e subito sul client; mentre nel caso di recordset aggiornabili si fa lavorare il Server di Database (ma attenzione al maggior carico che di lavoro che gli si impone e quindi alla minore scalabilità).
L’utilizzo dei cursori lato Client è inoltre consigliabile quando tra Server e Client si frappone una connessione lenta, instabile o temporanea (è il classico caso di Internet e delle postazioni connesse in modo intermittente, p.es. gli agenti di una società che si connettono al server centrale via modem). In questo modo sarà possibile usare una Connection per aprire un cursore lato Client, chiudere la Connection (magari scollegarsi anche da Internet) e continuare a lavorare con il Recordset ed eventualmente salvarselo su disco in locale (con l’apposito metodo Save).
La proprietà Source imposta il comando, la tabella, la query SQL o la Stored Procedure che rappresenta la sorgente del recordset. E’ possibile passare alla proprietà Source una stringa (è il classico caso della "SELECT * FROM…") o un riferimento ad un oggetto Command (vedi l’esempio nella sezione relativa a quest’ultimo); il valore di lettura (cioè quello che viene restituito leggendo la proprietà) è invece sempre una stringa.
La proprietà ActiveConnection altri non è che la nostra connessione creata in precedenza, ovvero l’oggetto Connection tramite il quale si vuole ottenere l’apertura del Recordset. Come detto, qualora non venga indicata una Connection esistente, ne verrà creata una nuova; in questo secondo caso nel metodo Open si dovrà indicare la ConnectionString al posto dell’oggetto Connection.
La proprietà CursorType stabilisce il tipo di cursore che si vuole utilizzare. I tipi sono quattro ma non tutti sono supportati da ogni OLEDB Provider (nel caso del Jet manca il primo dell’elenco): ForwardOnly, Static, Keyset e Dinamic in ordine crescente di dispendio di risorse. :-)
- Il ForwardOnly è il cursore di default e permette una sola passata nel recordset, solo in avanti, e ovviamente a fronte delle limitazioni è quello che ha le performance migliori. Va benissimo per esempio per popolare una griglia.
- Lo Static è una specie di fotografia scattata al momento dell’apertura. Può essere usato anche per aggiunte o cancellazioni ma non permette di vedere alcuna modifica effettuata da altri utenti sugli stessi dati. Quando la CursorLocation è adUseClient il cursore è per forza di cose uno Static. E’ importante notare che anche lo Static può essere un cursore aggiornabile (l’aggiornabilità o meno dipende solo dalla proprietà LockType), ovviamente potrebbero esserci più di frequente problemi da gestire per aggiornamenti eseguiti sugli stessi dati da altri utenti.
- Il Keyset è un cursore che permette di vedere le modifiche e le cancellazioni fatte da altri utenti sugli stessi dati senza bisogno di fare un Requery; non sono visibili invece le aggiunte effettuate da altri utenti dopo l’apertura del Recordset.
- Il Dynamic è il cursore più dispendioso e più completo. Sono visibili tutte le aggiunte, modifiche e cancellazioni fatte da altri utenti e tutti i tipi di movimenti. Non è supportato dall’OLEDB Provider per Jet.
E’ importantissimo tenere presente che, nonostante noi possiamo richiedere uno qualunque di questi quattro cursori, verrà generato sempre il cursore che più si avvicina alla richiesta qualora quello esatto non sia disponibile, e ciò SENZA generare un messaggio d’errore.
Ciò si giustifica con il fatto che tramite ADO è possibile accedere a numerose ed eterogenee fonti di informazione, a volte nemmeno organizzate in forma di DataBase relazionale; il codice utilizzato per accedere ai dati è inoltre praticamente lo stesso in ogni occasione e gli oggetti ADO devono poter essere utilizzati anche da linguaggi molto diversi tra loro (pensate ad esempio all’utilizzo degli ADO in una pagina HTML tramite VBScript o Jscript).
Sarebbe quindi eccessivamente onerosa la gestione degli errori e la logica what/if per accedere ai dati se ogni volta che una caratteristica da noi richiesta non fosse disponibile venisse generato un errore.
Diventa perciò spesso necessario utilizzare il metodo Supports dell’oggetto Recordset che permette di leggere se le caratteristiche che ci interessano sono effettivamente supportate dal Recordset aperto o meno; cioè eseguendo un controllo sulle funzionalità del Recordset posteriore alla sua apertura senza dare nulla per scontato.
La proprietà LockType identifica il tipo di blocco che viene imposto ai record nel Recordset e quindi stabilisce anche le possibilità di aggiornamento. I tipi di blocco sono: ReadOnly (default), Pessimistic, Optimistic e BatchOptimistic.
- Il ReadOnly permette (ovviamente) solo la lettura. Io lo uso in combinazione con una localizzazione adUseClient ed un tipo di Recordset Static o ForwardOnly per popolare controlli di riepilogo (griglie, combo, report ecc.).
- Il Pessimistic è l’opposto e garantisce che tutte le modifiche ad un record vadano a buon fine, infatti il Record è bloccato per tutti gli altri utenti a partire dalla prima modifica fino alla chiamata dell’Update.
- L’Optimistic permette l’aggiornamento ma blocca il record solo al momento della chiamata dell’Update; è possibile perciò che nel tempo intercorso tra l’inizio della modifica del record (rs!Nome = mstrNome ecc.) ed il comando Update altri abbiano modificato i dati, nel qual caso verrà generato un errore.
I tre tipi precedenti corrispondono ai diversi tipi di Locking presenti anche nei DAO.
- Il locking BatchOptimistic, invece, è tipico degli ADO e permette un’aggiornamento di più record in una volta sola; in pratica è possibile modificare un record, spostarsi sul successivo, modificarlo, spostarsi di nuovo ecc. e infine richiamare un unico UpdateBatch che inserirà tutte le modifiche in una volta sola.
Ovviamente in questo caso le possibilità di conflitti sono superiori però questo tipo di locking è molto valido in tutti quei casi dove è consigliato un cursore lato Client (connessione con il Server lenta o intermittente ecc.).
Per utilizzare il locking BatchOptimistic bisogna abilitare la libreria dei cursori lato client (CursorLocation = adUseClient). Inoltre bisogna notare che, sempre nel caso di cursore localizzato sul Client, il locking Pessimistic non è disponibile.
Finalmente possiamo passare alle istruzioni che permettono di aprire il Recordset.
Per le cose dette sopra ho optato, nella maschera frmProgrammatori, per un Recordset localizzato sul Server, di tipo Keyset e con locking Optimistic. Come per la Connection, piuttosto che settare le proprietà una ad una, le stesse verranno passate come argomenti del comando Open.
Nella form frmProgrammatori l’oggetto Recordset viene definito nella sezione Dichiarazioni
Private rsProgrammatori As ADODB.Recordset
|
e nell’evento Form_Load viene settata la proprietà CursorLocation e viene aperto il Recordset
Set rsProgrammatori = New ADODB.Recordset
rsProgrammatori.CursorLocation = adUseServer
rsProgrammatori.Open "SELECT * FROM Programmatori ORDER BY Cognome;", _
cnAdoTutor, adOpenKeyset, adLockOptimistic, adCmdText |
Il primo parametro passato, una stringa, è conservato nella proprietà Source ed è un comando SELECT SQL, per fare in modo che i nomi dei programmatori vengano restituiti in ordine alfabetico.
Seguendo l’ordine della sintassi gli altri parametri passati sono la ActiveConnection, il CursorType ed il LockType.
L’ultimo parametro serve per informare l’OLEDB Provider che la Source è un comando testuale e non una Stored Procedure, una Tabella, un oggetto Command o quant’altro; si velocizza così l’esecuzione dell’apertura.
Come per la Connection, l’oggetto Recordset viene chiuso e distrutto nell’evento Form_Unload:
rsProgrammatori.Close
Set rsProgrammatori = Nothing |
Bisogna ricordare infine che le proprietà CursorLocation, Source, ActiveConnection,
CursorType e LockType possono essere impostate solo su un oggetto chiuso, ovvero quando
l’oggetto è aperto si trasformano in ReadOnly. |
Indietro (Aprire la connessione) | Indice | Avanti (Associazione controlli/campi)
|