ASP e database
In questa sezione ci occuperemo dell’utilizzo per cui è nato ASP e che quindi risulta essere il più interessante aspetto di questo linguaggio di scripting: l’interfacciamento con i database ODBC compatibili.
Innanzitutto ci occuperemo di approfondire alcuni aspetti della tecnologie ODBC e ADO, in seguito faremo riferimento con un semplice esempio, ai metodi che ASP offre, per accedere on-line ad un database.
In questo capitolo, si danno per scontate, la conoscenza di SQL e la sintassi di ASP, quest’ultima per altro descritta nel capitolo precedente.
4.1 ODBC, IDC e ASP
Nell’ambito di una standardizzazione, che le permettesse di vendere i suoi prodotti anche a chi proveniva da altri strumenti, per quel che riguarda i database, la Microsoft introdusse nel 1991, l’interfaccia ODBC per poter fare interagire DBMS, sistemi operativi e protocolli di rete anche diversi tra loro.
ODBC rende quindi possibile, l’utilizzo di qualunque DBMS a patto che esso fornisca i driver per l’interfaccia. Lo sviluppo di Internet, come più volte affermato, ha poi deviato gli sforzi dei programmatori, affinché gli utenti potessero interagire con i DBMS tramite un browser, ovvero permettere la consultazione on-line di basi di dati. A tale scopo Microsoft ha associato ai suoi Web Server, oltre alla possibilità di utilizzare l’interfaccia ODBC, la tecnologia IDC (Internet Database Connector) ed infine, per rendere più semplice la programmazione e proporre una alternativa ai programmi CGI, ha introdotto ASP.
Partiamo occupandoci di IDC. Internet Database Connector è uno strumento che può essere utilizzato per spedire queries ad un database e formattare i dati che ritornano, in una pagina HTML. In figura è illustrato come IIS e Personal Web Server consentono l’accesso a un database:
I Web browser inviano richieste ai server Internet usando il protocollo HTTP; i server Web rispondono alle interrogazioni con documenti HTML grazie proprio a IDC.
IDC usa due tipi di file per controllare l’accesso al database e la generazione del documento HTML di risposta:
-
file .idc Internet Database Connector
-
file .htx HTML extension
I file .idc contengono le informazioni necessarie per connettersi all’appropriato ODBC data source e consentire l’esecuzione di istruzioni SQL. Inoltre questi file contengono informazioni sul nome e la locazione del file HTML.
I file .htx contengono i template per il documento HTML che viene restituito al Web browser dopo che i dati spediti hanno interagito con il database attraverso IDC.
Per usare IDC lo strumento è ASP, il quale nasconde sia all’utente che al programmatore la struttura e la costruzione dei file .idc e .htx.
4.2 ASP e ADO
Abbiamo visto come ODBC sia uno standard, che agisce ad un livello molto alto tra database e applicazione. Per utilizzare i driver ODBC, e quindi poter leggere un database, ASP si serve della tecnologia ADO (ActiveX Data Objects) sviluppata da Microsoft pe il suo linguaggio ActiveX. Tramite ADO è comunque possibile connettere una applicazione anche a database non ODBC compatibile quali ad esempio OLE DB.
Per identificare il database su cui lavorare, gli script ADO hanno bisogno che sia specificato un DSN (data source name) che univocamente specifichi il nome e il “luogo fisico” dove il database si trova. A sua volta il DSN contiene le informazioni che riguardano la configurazione del database, le specifiche sulla sicurezza, dove e come sono allocati i dati e può registrare le modifiche del file di log.
ODBC mette a disposizione tre tipi di DSN: User, System o File.
Il System DSN, permette agli utenti di avere un login ad un server per l’accesso ad un database
Lo User DSN controlla l’accesso di determinati utenti secondo le specifiche di sicurezza del server.
Il File DSN, che mantiene il form del text file, permette l’accesso a diversi utenti e facilita il passaggio di dati da un server ad un altro semplicemente copiando il File DSN.
I primi due sono mantenuti all’interno del registro di sistema del S.O. Nel corso del nostro studio faremo riferimento al File DSN ed in particolare a quello che identifica i database Access.
Per utilizzare ADO, occorre disporre della dll msado15.dll invocata dal programID, ADODB.
Gli oggetti di ADO, sono sette, ma tutti sono in qualche modo collegati con l’oggetto Connection, quello che permette di connettere l’applicazione ASP con un database ODBC compatibile. Quindi una volta dichiarato un oggetto Connection, è possibile gestire gli errori di connessione attraverso l’oggetto Error. Oppure possiamo compiere operazioni sul database usando l’oggetto Command, grazie al quale è possibile specificare stringhe che possono essere query o comandi per interagire con la base di dati. A sua volta command, permette di definire parametri all’interno delle stringhe di comando utilizzando l’oggetto Parameter. In alternativa all’uso di Command, ADO da la possibilità di accedere ai record di un database utilizzando l’oggetto Recordset che a sua volta sfrutta i metodi dell’oggetto Field attraverso il quale è facile spostarsi tra i campi di una tabella di un database.
Per ognuno di questi oggetti, esistono diversi metodi e il loro approfondimento va forse oltre lo scopo di questo lavoro. Ci limiteremo allora a presentare le caratteristiche dei metodi che verranno usati nell’esempio che presentiamo, dove lo scopo sarà quello di implementare le operazioni basilari che si devono poter compiere su un database.
4.3 Un piccolo esempio
Il modo migliore per capire come sia possibile interagire con una base di dati utilizzando ASP, è quello di studiare un semplice esempio e su di esso compiere le operazioni elementari come inserzione, cancellazione, ricerca e visualizzazione dei dati. Considereremo un semplice database Access costituito da una sola tabella, che rappresenta i dati associabili ad un libro e discuteremo ognuna delle operazioni sopra citate.
4.3.1 Connessione
Prima di procedere nell’esempio, vediamo in che modo si stabilisce la connessione tra il file ASP e il database. I metodi sono diversi e nel seguito gli utilizzeremo indifferentemente, tutti . In questo esempio, per quel che riguarda la visualizzazione, la connessione avviene usando l’oggetto ADODB.RecordSet:
Set rst = Server.CreateObject(“ADODB.recordset”)
rst.Open strQuery, strProvider
Con il metodo rst.open apriamo materialmente la comunicazione con il database che si trova sul server, nel percorso individuato attraverso la stringa strProvider e definiamo anche l’interrogazione (in questo caso statica) che si vuole effettuare sul database e che viene letta attraverso la stringa strQuery.
strProvider=”DRIVER=Microsoft Access Driver (*.mdb); DBQ=” & Server.MapPath(“/”) & “\asp\applic\motore\libri.mdb;”
strQuery=”SELECT * FROM tablibri WHERE titolo=’”&titolo&”‘ OR autore=’”&autore&”‘ OR categoria=’”&cat&”‘ OR editrice=’”&ed&”‘”
Su strQuery non c’è molto altro da dire, mentre è interessante porre l’attenzione su strProvider. Notiamo infatti che per definire il path dove si trova il file Access, utilizziamo il metodo dell’oggetto Server, MapPath: in questo modo rendiamo il percorso “relativo” e non assoluto. Ciò però potrebbe comportare problemi di carico sul server. Se allora il programma viene sviluppato solo per una macchina e non si prevede di dover in futuro, esportare le pagine realizzate su altri server, è preferibile usare la seguente modalità per definire il path:
strProvider=”DRIVER=Microsoft Access Driver (*.mdb); DBQ=”& “c:\inetpub\wwwroot\asp\applic\motore\libri.mdb;”
Infatti in questo caso specifichiamo il path assoluto sulla macchina che stiamo utilizzando.
Il secondo metodo, che utilizzeremo per l’inserimento e la cancellazione di un record, sfrutta la seguente sintassi:
Set cn = Server.CreateObject(“ADODB.Connection”)
cn.Open strProvider
In questo caso ci limitiamo a connettere il database con la nostra pagina. Quindi non abbiamo ancora definito nessuno strumento per lavorare sui record. Per farlo dobbiamo definire il seguente oggetto:
Set cm= Server.CreateObject(“ADODB.Command”)
Set cm.ActiveConnection = cn
Ora cm, ci permetterà di svolgere update, delete e insert, sulla base di dati.
Il terzo metodo per la connessione sfrutta invece le proprietà del driver odbc ed è un metodo relativamente semplice e legato al file global.asa, di cui tratteremo in dettaglio nella seconda parte. Per ora analizziamo il metodo con cui avviene tale connessione. In questo caso occorrerà interagire con il sistema operativo (nel nostro caso Windows 98). All’interno del pannello di controllo occorre selezionare la voce Origine Dati ODBC:
e selezionare poi il foglio DSN System:
Dopo aver premuto il tasto aggiungi occorre selezionare il driver per il database che si sta utilizzando (nel nostro caso il database è un file Access) e premere fine. A questo punto appare l’ultima schermata, quella che ci chiederà il DSN da associare e il percorso dove si trova il database da leggere. Ultimate queste operazioni, la nostra base di dati sarà localizzata da ADO, con il nome che gli abbiamo assegnato. Quest’ultimo metodo sarà quello che utilizzeremo per il nostro esempio di sito commerciale.
4.3.2 Visualizzazione
Passiamo ora ad analizzare il nostro semplice esempio, partendo dalla più banale delle operazioni, la visualizzazione dei campi di un semplice database, costituito solo da una tabella. Questa limitazione non pregiudica la generalità del metodo che presenteremo: infatti le procedure che utilizziamo ora, saranno poi usate anche nell’esempio finale di gestione di un sito e-commerce.
Lo script per visualizzare i dati nella tabella è la seguente:
|
Scrittura dei record di un database
<% ON ERROR RESUME NEXT IF rst.EOF THEN Response.Write “Non ci sono record nel database” ELSE FOR i = 1 to rst.Fields.Count –4 Response.Write “<td width=200> “& rst(i).Name &”</td>” NEXT WHILE NOT rst.EOF FOR i = 1 to rst.fields.count – 4 Response.Write “<td align=left valign=top bgcolor=’#ffffff’>” & rst(i) &”</td>” NEXT Response.Write “<td width=250 bgcolor=’#fad336′> <a href=’libri.asp?ID=”&rst(0)&”‘> ‘”&rst(2)&”‘ </a></td>” rst.MoveNext WEND END IF %> |
Come già detto in precedenza, utilizziamo un oggetto ADO di tipo recordset: ciò ci permette di definire in pratica un cursore che si muove sulle tuple della tabella. Per accedere quindi ad un campo della tabella, la sintassi è la seguente:
rst(i) oppure rst(“nome_campo”)
per muoversi invece su un’altra tupla si usa il metodo:
rst.MoveNext
Più avanti vedremo altre caratteristiche dell’oggetto RecordSet relative alle operazioni che si possono compiere su un database.
4.3.3 Cancellazione e ordinamento
Per cancellare e ordinare i dati di una tabella, sfrutteremo in parte lo script per la visualizzazione, aggiungendo dei controlli che ci permetteranno di definire dei bottoni per l’ordinamento secondo i diversi campi e per la cancellazione. Le righe di codice da aggiungere sono le seguenti:
|
Controlli per l’ordinamento rispetto ad un campo
<% ‘Questa if serve per definire il pulsante per ogni campo ‘Che ci permette di ordinare la tabella per ogni campo
if request.form(“sort”)<> “” THEN StrSort=request.form(“sort”) ELSE ‘decido rispetto a quale campo ordinare la tabella come default StrSort=”AUTORE ASC” END IF %> |
|
Definizione del campo per la Cancellazione
<% ‘In questa IF identifico qual è il record che voglio cancellare tramite la chiave primaria della tabella ovvero ID1 IF Request(“ID”) <> “” THEN strIDNum=Request(“ID”) ‘Da notare che in questo caso apro la connessione con il database ‘Utilizzando ADODB.Connection. Questo perché sui record del database non devo compiere operazioni set objConn = server.createobject(“ADODB.Connection”) objConn.Open strProvider ‘In questo caso definisco l’oggetto cm utilizzando ADODB.command set cm = Server.CreateObject(“ADODB.Command”) cm.ActiveConnection = objConn cm.CommandText = “DELETE FROM Tablibri WHERE ID1 = ” &strIDNum cm.Execute END IF %> |
4.3.4 Inserimento
Ecco infine lo script per l’inserimento di un record nel nostro database:
|
Inserimento di record in una tabella
<% titolo=request.form(“titolo”) autore=request.form(“autore”) cat=request.form(“cat”) ed=request.form(“editrice”) anno=request.form(“anno”) prezzo=request.form(“prezzo”) testo=request.form(“testo”) imm=request.form(“imm”) collana=request.form(“collana”)
Set cm= Server.CreateObject(“ADODB.Command”) Set cm.ActiveConnection = cn ‘Definiamo l’azione di inserimento su tutti i campi cm.CommandText = “INSERT INTO tablibri (autore, titolo, categoria, editrice, anno, prezzo, testo, imm, collana) VALUES (‘”&autore&”‘,’”&titolo&”‘,’”&cat&”‘,’”&ed&”‘,’”&anno&”‘,’”&prezzo&”‘,’”&testo&”‘,’”&imm&”‘,’”&collana&”‘)” ‘Definiamo i parametri della query cm.Parameters.Append cm.CreateParameter(“type”,200, ,255)
cm(“type”) = Request(“SeedType”) cm.Execute
%> |
4.3.5 L’oggetto RecordSet
Abbiamo visto in precedenza alcune proprietà dell’oggetto RecordSet ma vale la pena approfondirne alcuni aspetti, dato che questo oggetto risulta essere un mezzo versatile e potente, per la gestione dei dati in un database creando un set di record e le operazioni per operare su di esso.
Cominciamo ad esempio, con le operazioni di insert, delete e update. Abbiamo visto nei paragrafi precedenti come sia possibile utilizzare l’SQL standard per svolgere queste azioni. Un altro via, è utilizzare i metodi che RecordSet mette a disposizione. Supponiamo allora di voler inserire un record in una tabella della nostra base di dati. Dopo essersi connessi utilizzando Server.CreateObject(“ADODB.recordset”) e rst.Open strProvider, per inserire un nuovo record basterà scrivere:
|
rs. AddNew rs(“Nome_campo1″)=valore1 rs(“Nome_campo2″)=valore2 …. Rs.update |
Analogamente utilizzando il metodo:
rs.delete
elimineremo il record che si sta puntando (anche se è possibile specificare quale record cancellare). Un altro importante metodo è rs.close i che chiude la connessione stabilita con il database su cui si sta operando.
Un’altra importante caratteristica di RecordSet è la possibilità di definire dei parametri sulla connessione che si effettua con un database. I più importanti sono CursorType e LockType e si definiscono nel seguente modo:
Rs.Open Connessione,CursorType,LockType
Il CursorType definisce il tipo di cursore cioè la rappresentazione dei records e definisce anche il tipo di viste possibili su di essi. I tipi di cursore sono quattro:
-
Cursore di default (valore 0): Definisce un cursore statico ad eccezione del fatto che permette spostamenti solo in avanti e non indietro dato che questo cursore non deve tenere traccia dei record aggiunti, modificati o cancellati da altri utenti
-
Cursore Keyset (valore 1): possono “vedere” delle modifiche apportate da altri utenti, nonché spostarsi tra i record in avanti ed indietro. Non si possono invece vedere i record aggiunti o eliminati da altri utenti
-
Cursori Dinamici (valore 2): Questo tipo di cursore è in grado di vedere qualsiasi cosa: modifiche, aggiunte e cancellazioni fatte anche da altri utenti e consentono qualsiasi spostamento
-
Cursori Statici (valore 3): in questo caso è possibile spostarsi avanti e indietro ma non è possibile rilevare le modifiche ai dati apportate da altri utenti
Il valore di LockType determina che tipo di blocco il database deve usare quando viene aperto un RecordSet; questo ai fini del controllo di concorrenza sugli accessi ai dati da parte di più utenti contemporaneamente. I tipi di lock sono:
-
AdLockReadOnly (valore 1): i dati possono essere solo letti
-
AdLockPessimistic (valore 2): i dati vengono bloccati (cioè non sono modificabili da altri utenti) appena qualcuno comincia ad effettuare operazioni di modifica, così da garantire un’assoluta integrità degli stessi ma a costo di spiacevoli rallentamenti del sistema; infatti finche l’utente non termina le proprie modifiche quei dati rimangono bloccati
-
AdLockOptimistic (valore 3): questo tipo di blocco, crea un buffer temporaneo in cui vengono conservati gli aggiornamenti e le modifiche, mentre i dati originali sono ancora accessibili agli altri utenti. I dati vengono protetti dalle modifiche degli altri utenti solo nel momento in cui viene lanciato un comando di aggiornamento (update)

Commenti recenti