Gestire le query all'esterno dell'ASP |
| A cura di Davide Bianchi |
Mescolare i linguaggi (SQL ed ASP) non e' mai una buona cosa,
utilizzando un paio di semplici accorgimenti e' possibile gestire
le Query SQL all'esterno dei file ASP che le richiamano, rendendo
il codice piu' pulito e facilmente mantenibile.
|
| Manutenzione difficile |
A tutti sara' capitato: di dover mettere le mani su del codice
ASP non fatto da noi e, nella fattispecie, di dover modificare
una Query, per poi scoprire che quella maledetta query era
richiamata da 52 pagine ASP diverse. Risultato: una query=52 pagine modificate! Dopo l'ennesima disavventura del tipo, ho finalmente deciso a mettere mano ad un sistema 'umano' per gestire questo tipo di problemi.
|
|
| Tenere l'SQL fuori dall'ASP |
Cosa ci vuole per gestire le query in un modo 'decente'? In fondo una
query altro non e' che un blocco di testo ASCII, a cui possono essere
aggiunti dei parametri da valorizzare al momento di eseguirla, niente
altro. Ecco la mia pensata quindi: definire le query in un file (ASCII) quindi leggere il testo della query da ASP utilizzando l'FSO mediante una semplice funzione, utilizzare un'altra funzione per fare la sostituzione dei parametri et-voila', eseguire la query. In questo modo si ottengono tre vantaggi:
|
|
| Il formato delle Query |
Dato che non sono richieste informazioni 'apocalittiche' per questo
tipo di attivita', ho deciso di gestire le query con un semplicissimo
formato: il file delle query e' composto da linee, ogni linea
rappresenta una query, ogni query e' composta di due parti
separate da ';' Codice identificativo ; testo della query Non ci sono limiti alla lunghezza del codice e del testo della query, eventuali spazi prima e dopo il codice vengono 'ingoiati' dalla funzione che legge la query. Eventuali parametri da sostituire nella query (clausola WHERE o ORDER BY) sono indicati con !n dove 'n' e' un numero progressivo. Per quanto riguarda i parametri, qualunque sequenza di caratteri che non abbia significato in SQL potrebbe essere utilizzata ho scelto '!' semplicemente perche' sono sicuro che nessun dialetto SQL utilizza questa sequenza (mentre molti usano '#' come indicatore della data o $ come carattere jolly). Un generico 'file di query' potrebbe essere il seguente:
TuttiGliArticoli;SELECT Titolo, Autore, DataPubblicazione FROM Documenti WHERE Documenti.IDTipo=0
Dim sql sql = RecuperaQuery( "TuttiGliAutoriPerAnno", query.txt )avremmo pochi dubbi su cosa sta' facendo quel pezzo di codice suppongo...
|
|
| Il codice: trovare le query |
A questo punto ci manca il codice per reperire le query dal file,
scomodiamo pertanto il FSO (FileSystemObject) per fare la parte
(nota: il codice e' in JavaScript e non in VBScript):
/*
* Cerca una query specificata per ID all'interno del
* file indicato, ritorna la query cercata o NULL se
* non trova nulla
*
*/
function RecuperaQuery( qryID, fileName )
{
var fso; // FileSystemObject
var file; // Fiile usato per leggere le query
var elem; // elementi della query
var query = null; // query da ritornare
var ro = / /g; // elimina spazi
// Creo un nuovo oggetto FileSystem
fso=new ActiveXObject( "Scripting.FileSystemObject" );
// accedo al file delle Query
file = fso.OpenTextFile( fileName )
// elimino gli spazi all'interno del codice
qryID = qryID.replace( ro, "" );
// ciclo e leggo tutte le query
while( ! file.AtEndOfStream )
{
// leggo la singola query
qry = file.ReadLine();
// parserizzo suddividendo la query in Codice e
// Testo ed elimino gli spazi
elem = SeparaQuery( qry, null );
elem[0] = elem[0].replace( ro, "" );
// verifico di aver trovato la query che cercavo
if( qryID == elem[0] )
{
// ritorno la query trovata
query = elem[1];
break;
}
}
// chiudo il file delle query
file.close();
// ritorno la query trovata o Null
return query;
}
Con questo semplice pezzo di codice siamo in grado di reperire le
query leggendole dal file. L'unica parte di codice che potrebbe non
essere molto chiara e' l'utilizzo della
replace per eliminare gli spazi.Qui' sto utilizzando una features del JScript che consente di usare una Regular Expression per effettuare un ricerca/sostituisci all'interno del testo. Una trattazione completa delle Regular Expression e' al di la' degli scopi di questo articolo (sono stati scritti libri interi sull'argomento), bastera' sapere che lo scopo della funzione e' l'eliminazione di qualunque spazio all'interno della stringa. N.B. non ho convertito il testo in maiuscolo/minuscolo, proprio per lasciare piu' possibilita' di scelta all'utente su come codificare le query. Eventualmente potrebbe essere utile fare la conversione e mettere tutto in minuscolo o maiuscolo.
|
|
| Separare il codice dalla query |
La funzione
RecuperaQuery,
fa riferimento ad una fantomatica
SeparaQuery,
che dovrebbe dividere la linea letta ritornando i due elementi che
la compongono: il Codice e la Query vera e propria, questa
e' la funzione che ci serve:
/*
SeparaQuery
Separa una 'query' letta dal file in due elementi:
un codice ed una stringa che vengono ritornati
in un array costruito per l'occasione.
Parametri:
query e' la query letta dal file
separatore e' il carattere usato per dividere i due pezzi
*/
function SeparaQuery( query, separatore )
{
var ro;
// se il separatore non e' specificato assumo ";"
if( sep == null )
{
ro = new RegExp( ";", "g" );
}
else
{
ro = new RegExp( sep, "g" );
}
return qry.split( ro );
}
L'uso di una RegularExpression per fare il lavoro ci mette al
riparo da limitati errori di scrittura nel file delle query:
se mettiamo due ; uno accanto all'altro (codicequery;;stringaquery),
i due ';' verranno interpretati come uno solo dalla RegExp,
ritornando quindi sempre la riga esatta!
|
|
| Sostituire i parametri |
A questo punto manca la parte di codice che sostituisca nella
stringa-query i vari parametri, usiamo di nuovo la potenza delle
Regular Expression:
/*
SostituisciParametro
Sostituisce il parametro indicato nella query
con il valore indicato
query query da elaborare
paramNumber numero di parametro da sostituire
value valore da inserire
ATTENZIONE: se 'paramNumber' non viene trovato,
non viene fatta nessuna sostituzione ne'
si segnala alcun errore.
*/
function SostituisciParametro( query, paramNumber, value )
{
var pos;
var newQuery = "";
// preparo la RegularExpression per fare la sostituzione,
// usando 'gi' sostituisco tutto (global) ed ignoro maiuscole
// e minuscole (ignore case)
var ro = new RegularExpression("!" + paramNumber, "gi")
// effettuo la sostituzione
newQuery = query.replace( ro, value );
// ritorno la nuova query
return newQuery;
}
|
|
| Un semplice esempio d'uso |
Il codice seguente legge una query dal nostro file, vi sostituisce
alcuni parametri ed utilizza la query risultante.
Dim conn
Dim rs
Dim query
Set conn=Server.CreateObject("ADODB.Connection")
conn.Open "DSNNAME"
' recupero la query...
query = RecuperaQuery( "TuttiIRecordPerAnno",
Server.MapPath("query.lst") )
query = SostituisciParametr( query, 1, 1999 )
' faccio qualche cosa con il risultato
Set rs=conn.Execute( query )
'...
Non e' difficile intuire cosa faccia questo pezzo di codice,
e l'assenza di codice SQL messo in mezzo rende la manutenzione
assai piu' semplice.
|
|
| Conclusione e miglioramenti |
Il codice presentato e' gia' un notevole miglioramento rispetto al
mettere il codie SQL direttamente dentro all'ASP, un ulteriore
miglioramento protrebbe essere la lettura di tutto il file query
all'inizio (nel global.asa ad esempio), in modo da fare poi il
'pescaggio' delle query da un array in memoria, questo velocizzerebbe
molto le cose, soprattutto quando le query diventano TANTE. Un altra miglioria che ptrebbe essere fatta e' l'uso di un array di parametri nella SostituisciParametri, in modo da poter specificare tutti i parametri in una sola linea.
|
|
Comments Max length of comments: 1000 chars. |
nessun commento.
Add a comment (max 1000 chars)
|
| Author |
Davide Bianchi,
works as Unix/Linux administrator for a "network security" company of Haarlem. Contacts: mail: davide AT onlyforfun.net , ICQ: 268751033, Jabber: davideyeahsure AT gmail.com Skype: davideyahsure |
| Contribuire | Volete contribuire? Leggete come! |
| Copyright | This site is made by me with blood, sweat and gunpowder, if you want to republish or redistribute any part of it, please drop me (or the author of the article if is not me) a mail. |
This site isn't optimized for vision with any specific browser, nor
it requires special fonts or resolution.
You're free to see it as you wish.
Last Update: 04/12/2008