Accesso ai dati con DAO e MFC |
A cura di Davide Bianchi | Accedere ai dati direttamente con le MFC ed il DAO. |
Tanti oggetti, cosi' poco tempo... |
L'accesso e la manipolazione dei database sono una delle attivita'
"normali" per quasi qualunque programma, non conta tanto cosa il
programma fa', in un modo o nell'altro una delle sue attivita' sara'
quella di accedere a dei file per scrivere o leggere delle informazioni
che dovranno poi essere rilette in seguito. Una delle funzionalita' principale dei database e' per l'appunto quella di memorizzare le informazioni in modo che sia rapido ritrovarle in seguito. Pochi sistemi pero' hanno questo conecetto di "database" cosi' pervasivo (l'AS 400 per esempio, per cui ogni file ha una struttura di record). In generale i programmi possono salvare le informazioni in molti modi diversi e leggerle in molti modi diversi. Per accedere ad un database (di qualunque tipo) in ambiente Windows vi sono svariati modi. Il principale e' quello di utilizzare l'interfaccia generica di ODBC, che consente l'accesso ad un qualunque database per cui e' presente un driver di interfaccia. ODBC e' un ottimo sistema di accesso, se non che le sue API di comunicazione sono piuttosto complesse, e non sono idonee per l'accesso tramite linguaggi come ASP o Visual Basic. Per ovviare a questo problema la Microsoft ha sviluppato ADO, Activex Data Object, che, come dice il nome, e' un componente di tipo ActiveX che consente l'accesso ai dati tramite interfaccia ad oggetti. Essendo un componente ActiveX, la sua interfaccia viene "esposta" tramite l'accesso ad oggetti di default. Quindi e' ottimo per il collegamento tramite Visual Basic ed altri linguaggi simili. Per consentire un accesso ai dati anche in modo "remoto", Microsoft ha poi sviluppato l'interfaccia OLE DB, che consente un accesso diretto ai database mediante una serie di oggetti che possono essere richiamati e pilotati mediante OLE. Purtroppo l'OLE non e' una tecnologia cosi' tanto semplice ne' tanto "leggera" dal punto di vista del consumo di risorse. Un altra via per accedere ai dati e' quella di utilizzare direttamente il DAO, Data Access Obiect. DAO si trova piu' o meno a meta' tra l'ADO e l'OLE DB. Si tratta infatti di un'insieme di oggetti connessi ed API di controllo che consentono l'accesso ai database di tipo Access e ODBC in modo diretto (come ADO), ma senza tutte le complicazioni dell'OLE.
|
|
La struttura di DAO |
Il diagramma seguente riporta (molto semplificata) la struttura di
DAO, almeno per quanto riguarda gli oggetti di interesse piu' comune.
Una trattazione completa del DAO e' disponibile sul sito
Microsoft e nell'MSDN.
![]() Il DAO
DAO consente di avere attivi diversi WorkSpace, in ognuno dei quali possono essere attivi piu' database diversi. Ad ogni WorkSpace possono essere collegate diverse caratteristiche (Utenti, Password, parametri di controllo...). Notare che gli oggetti Error sono connessi al DBEngine e non alle singole WorkSpace/Database.
|
|
Quando usare DAO ? |
DAO e' la soluzione ideale se si vuole accedre tramite C/C++ ad un
database di tipo Access o ODBC, senza volere la complicazione delle
API di ODBC (DAO usa ODBC automaticamente se e' istruito a farlo),
inoltre, data la presenza di una serie di classi MFC di
"incapsulamento" di DAO, l'utilizzo mediante le MFC e' notevolmente
piu' semplice dell'uso delle OLE DB.
|
|
Come si usa DAO ? |
Ora inizia la parte interessante. L'utilizzo di DAO e' notevolmente semplificato se si utilizzano le corrispondenti classi MFC, tali classi sono identificate dal prefisso CDao. Per utilizzare le classi DAO occorre includere i file necessari per avere il supporto delle MFC, questo si puo' fare usando:
#include <afx.h> Per utilizzare DAO, per prima cosa occorre "inizializzare" il motore del database, questo si fa' richiamando la funzione AfxDaoInit(). Se la AfxDaoInit non e' richiamata, essa verra' richiamata automaticamente non appena si accede ad una delle classi DAO, quindi strettamente parlando il richiamo non e' obbligatorio, pero' e' buona norma inserirla per chiarificare cio' che il codice si propone di fare (e per evitare problemi il giorno che Microsoft modifica le MFC).
|
|
Workspace e Database |
La prima cosa da fare e' quella di creare un'oggetto
CDaoDatabase che ci
permette di accedere al database che vogliamo gestire. La creazione del CDaoDatabase puo' essere fatta in due modi: o usando CDaoWorkspace, oppure creando direttamente il CDaoDatabase, in questo secondo caso, un Workspace di default verra' creato automaticamente. I Database DAO possono essere di tipo Access (normale) oppure fonti dati di ODBC. L'unica differenza consiste nella creazione dell'oggetto Database associato, che nel caso di Access richiede solo il nome (path completo) del file .MDB corrispondente, mentre nel secondo caso richiede la stringa di connessione completa per il database stesso. DAO consente anche di creare il database da zero, questo si fa' usando l'apposito metodo Create dell'oggetto Database. Cosa piuttosto strana, creando il database .MDB con DAO si ottiene un database leggermente piu' compatto che usando Access (60Kb contro 72). Una volta che abbiamo il database abbiamo diverse possibilita' di gestione:
|
|
Leggere le informazioni con CDaoRecordset |
L'oggetto CDaoRecordset messoci a disposizione dalle MFC incapsula tutte
le necessarie funzionalita' per accedere ai dati di una o piu' tabelle
tramite una query SQL ed eseguire delle manipolazioni sugli stessi dati.
Ricordiamoci che una query (view) e' modificabile solo se e' fatta su non piu' di due tabelle, contiene tutti i campi obbligatori delle due tabelle (o tutti quelli che non hanno un default) e se le tabelle sono piu' di una, solo la tabella "figlia" e' modificabile. Per sintetizzare le possibilita' che una query con piu' di una tabella sia modificabile sono molto basse. Per creare un Recordset occorrono due cose: un CDaoDatabase attivo ed una query SQL valida. Dopo di che' usando:
CDaoRecordset recordset = CDaoRecordset( daoDb ); Il parametro type indica il tipo di recordset da aprire, i tipi supportati sono molteplici:
Il parametro opt indica delle opzioni aggiuntive per il recordset da aprire.
|
|
Leggere i dati del recordset |
Una volta che abbiamo il recordset aperto ed attivo, possiamo leggerne
i dati usando il metodo
GetFieldValue(), muoverci
tra i vari record usando
MoveNext(),
MovePrevious(),
MoveFirst() e
MoveLast(). L'accesso ai dati del recordset e' un po' complicato dal fatto che i dati sono memorizzati sotto forma di COleVariant, una particolare classe di variabili di tipo Variant che permette la memorizzazione di ogni tipo di valore, ma questo ci obbliga a "tradurre" ogni valore usando delle apposite macro-funzioni per poter accedere ai veri dati inseriti. Le macro funzioni V_ permettono di "tradurre" i valori variant nell'equivalente valore "normale" che puo' essere poi gestito. Per esempio, supponendo che il campo "x" contenga una stringa, per accedere al valore contenuto occorrera' fare:
CString campo;
/* reperisco il campo */
/* converto in stringa */
Vedere l'MSDN o la guida di Visual C per un'elenco completo delle macro V_ o per i dettagli sull'oggetto COleVariant.
|
|
Modificare i dati |
Il sistema piu' semplice per modificare i dati del database e' quello
di inviare delle Query di comando al motore del database usando il
metodo Execute dell'oggetto CDaoDatabase. Attenzione: il metodo Execute non puo' essere usato con query che ritornano valori (SELECT). Una funzione come la seguente: daoDb.Execute( "DELETE * FROM Tabella;"); Esegue la cancellazione di tutti i record della tabella indicata. Se la query inviata non e' corretta si verifichera' un'eccezione che dovra' essere recuperata e gestita, altrimenti il programma potrebbe crashare.
|
|
Terminare le operazioni |
Al termine delle operazioni e' buona norma chiudere tutti i Recordset
ed il Database richiamando i metodi Close di entrambi, quindi
terminare il "motore" di database richiamando la AfxDaoTerm( ); Questo concludera' le operazioni di gestione ed eliminera' dalla memoria una serie di strutture dati utilizzate in precedenza. Attenzione: il mancato richiamo della AfxDaoTerm() provoca il crash del programma alla terminazione (qualche schifezza dentro le MFC che non pulisce la memoria come dovrebbe), in un caso ha anche provocato il blocco della macchina con corrispondente reboot forzato.
|
|
Un semplice esempio |
Il codice di esempio presente consente la gestione di una mini-agenda,
questo codice e' sviluppato come Console-Application, quindi niente
finestre. La scelta di farlo Console-based ha permesso di concentrarsi
sulle funzioni di gestione del database e di ignorare i problemi di
gestione dell'interfaccia grafica. Per verificare il programma occorre Visual C++ versione 4 o superiore, probabilmente il codice e' compilabile anche con Borland, ma non ho provato quindi non sono in grado di dire quali modifiche ci siano da apportare al codice (se ce ne sono). Per compilare il programma create un nuovo progetto vuoto Win32 console, ed inserite i due sorgenti (DAO.CPP e DAO.H) nel progetto. Quindi dal menu' Project scegliete Propieta', selezionate il progetto e scegliete tra le Generalita' "Usa le MFC". Compilate ed eseguite. Il programma gestisce un database Access denominato DAODEMO.MDB, se il database non esiste, viene creato, viene creata una tabella chiamata Anagrafica con alcuni campi. Le funzionalita' di gestione implementate sono l'elencazione dei record, l'inserimento di un nuovo record e l'eliminazione di un record presente. Non e' stata implementata la modifica di un record esistente.
|
|
Bibliografia e riferimenti |
Microsft MSDN:
Create an .MDB File for Microsoft Access Databases - Article ID:
Q149558 |
L'autore | Davide Bianchi, pomposamente definito Software Engineer dal biglietto da visita, lavora per la Square bv, societa' olandese con sede a Roermond, che si occupa di sviluppo di software con orientamento grafico. Attualmente sta' lavorando in Java (e si diverte un sacco). |
Commenti | Vuoi mandare un commento su questo articolo ? Scrivi all'autore. |
Contribuire | Ti senti in grado di scrivere un articolo e vorresti vederlo pubblicato? Leggi come fare |
Copyright |
Il presente sito e' frutto del sudore della mia fronte (e delle mie dita),
se siete interessati a ripubblicare uno degli articoli, documenti o
qualunque altra cosa presente in questo sito per cortesia datemene
comunicazione, cosi' il giorno che faccio delle aggiunte potro'
avvisarvi e magari mandarvi il testo aggiornato.
|
Questo sito non e' ottimizzato per la visione con nessun browser
particolare, ne' per nessuna risoluzione particolare ne' impone
l'uso di font particolari. Siate liberi di vederlo come vi pare
e piace.
Ultimo aggiornamento: 01 Novembre 2000