nov 062009

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:

interazione_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:

pannello_controllo_odbc

e selezionare poi il foglio DSN System:

admin_odbc

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:

  1. 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

  2. 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

  3. 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

  4. 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:

  1. AdLockReadOnly (valore 1): i dati possono essere solo letti

  2. 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

  3. 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)

Leave a Reply

(required)

(required)