Search English (United States)  Italiano (Italia) Deutsch (Deutschland)  Español (España) Čeština (Česká Republika)
Tuesday, June 18, 2019 ..:: Articles » VB 6.0 » ADO, Parametri e affini ::.. Register  Login
 Download Minimize

  
 1. Introduzione Minimize

Dopo diversi anni di frequentazione dei forum dedicati a VB 6.0, ho notato che uno dei problemi ricorrenti nella gestione dei database è relativo all'inserimento ed aggiornamento dei dati.
Questo avviene nella grande maggioranza dei casi per gli utenti che usano il database gratuito di Access (MDB) in cui, com'è noto a molti, è necessario dargli in pasto i dati formattandoli come li vuole lui.

Sui forum ho visto stringhe di ogni tipo che assomigliavano più a scritture geroglifiche che a comandi SQL, tanto erano piene di virgole, apici, cancelletti, ... Per non parlare poi di funzioni come Format(), Mid(), Left(), ... Tutto questo perchè il database Access sarà pure gratuito, ma sembra un signorino schizzignoso: o fai come vuole lui oppure nisba! Nemmeno gli altri database scherzano, comunque.

Diciamo che se uno sviluppatore deve inserire od aggiornare un record che abbia anche solo:
- 2 o 3 date
- 7 o 8 stringhe
- ed il resto numeri
ha il suo bel da fare nel costruire la stringa del comando SQL.
Ti dimentichi un apice... e sei fritto. Roba da perderci ore e farsi venire il mal di testa.

Avete presente, vero, quelle lunghe ed interminabili stringhe dei comandi SQL? Del tipo:

INSERT INTO tabella 
(cognome, nome, indirizzo, luogo, datainizio, datafine, tipoevento) VALUES
('" & txtCognome.text & "','" & txtNome.Text & "','" & txtIndirizzo
& "','" & txtLuogo.Text & "'",#" & txtDataInizio.Text & "#,#"
& txtDataFine.Text & "#,'" & txtTipoEcento.Text & "')"

Consideriamo che qui abbiamo usato solo 6 campi, pensate quando se ne devono usare 15, 20, 30 o anche più! Vai te a cercare l'apice o la virgola dimenticati all'interno di una stringa SQL relativa ad una trentina e più campi...
Se poi, come troppo spesso mi è capitato di vedere, lo sviluppatore nomina i suoi controlli in maniera inadeguata come: Text1, Text2, Text3, Text4, ... Beh, Tanti auguri: quando sarà ora di manutenere la query dopo un paio d'anni non vorrei essere al suo posto!
Insomma, non credo serva aggiungere altro.

Adesso vi chiedo, vi piacerebbe un qualcosa di più semplice, che non vi faccia venire mal di testa, e che vi eviti di dover controllare con la lente d'ingrandimento la correttezza di una stringa SQL?

C'è? chiederete voi? Ma certo che c'è: sono i parametri di ADO!
Stranamente nei forum nessuno, o pochi, ne parla; oppure io sono stato così sfortunato da non leggere mai a tal proposito. Eppure sono come la manna dal cielo, tanto sono utili, comodi e versatili.

In questo articolo vedremo come utilizzarli per inserire ed aggiornare dati, utilizzando sia query parametriche, ovvero quelle che nei database blasonati si chiamano SP - Store Procedure, sia utilizzando delle query 'ad hoc', cioè query create direttamente nel codice, entrambe sempre usando i parametri.

Nel database allegato è già presente la query parametrica qryOggiParam che il Command di ADO definisce come una SP - stored procedure. Per facilitare il tutto, la query 'ad hoc' che costruiremo da codice eseguirà lo stesso identico compito della SP presente nel database, così avremo modo di confrontarle.

Nei prossimi paragrafi vedremo come implementare le classiche operazioni di INSERT, UPDATE e SELECT.


 Print   
 2. Command e Parameter - INSERT Maximize

 Print   
 3. Command e Parameter - UPDATE Maximize

 Print   
 4. Command e Parameter - VERSIONE 2.0 - 2 ottobre 2009 Minimize

ADO Parameters versione 2.0

Inizialmente volevo dedicare questa parte alla SELECT, ma in effetti mi sono reso conto che sarà sufficiente leggere il codice per capire come comporre una SELECT.
In particolare suggerisco di studiarsi bene la nuova routine RecordRicercaAvanzata del modulo frmEditRecord che è può essere molto utile per comprenderne l'uso, abbinata come sempre all'uso dei parametri di ADO.

Le novità di questa seconda parte sono molte. Nel file guida.txt troverete tutte le informazioni utili e raccomando di leggerlo. Ecco l'elenco delle novità principali:

- aggiunto il menu
- gestione pulsanti migliorata
- aggiunta la Ricerca Avanzata: consente ricerca su tutti i campi!
- migliorata la gestione delle finestre
- altri piccoli miglioramenti di poco conto
- ecc...

Ma la novità più importante è rappresentata da un gruppo di routine che consente di impostare i parametri di ADO in maniera straordinariamente semplice. Le ho riunite tutte in un modulo modADO.bas e sono:
- SetADOParameter
- RicavaTipoCampo
- RicavaDefinedSize
- ImpostaMaxLengthTextBox

Vediamone le firme:

Public Sub SetADOParameter(ByRef cmd As ADODB.Command, ByVal sTableName As String, _
        ByVal sFieldName As String, ByVal parValue As Variant)

Public Function RicavaTipoCampo(ByVal sTableName As String, ByVal sFieldName As String) As ADODB.DataTypeEnum

Public Function RicavaDefinedSize(ByVal sTableName As String, ByVal sFieldName As String) As Long

Public Sub ImpostaMaxLengthTextBox(ByRef f As Form, ByVal sTableName As String)

In pratica, invece di creare manualmente tutti i parametri utilizzando i metodi dell'oggetto Command CreateParameter e Parameters.Append come facevamo prima:

Set par = cmd.CreateParameter("@cognome", adVarChar, adParamInput, 50, txtCognome.Text)
cmd.Parameters.Append par

ora potremo indicare più semplicemente:

SetADOParameter cmd, sTabella, "cognome", txtCognome.Text

La cosa che ritengo molto utile è, come potete vedere, che la nuova routine SetADOParameter oltre ad essere molto più semplice da scrivere (una sola riga di codice), non sarà più necessario indicare :
1 - il tipo di dato
2 - la direzione del parametro (*)
3 - la dimensione del campo (per i campi di tipo testo)

Questo perchè SetADOParameter pensa a fare tutto questo lavoro al posto nostro, grazie proprio alle altre quattro routine elencato sopra. 

Il vantaggio non sta tanto nello scrivere una riga di codice anzichè due, ma nel fatto che non dovremo più andare a controllare nel database i valori necessari (vedi sopra 1, 2 e 3) il che francamente è la vare scocciatura.
Se poi, in futuro, cambiamo il tipo oppure la dimensione del campo saremmo costretti a rivedere tutte le impostazioni del relativo parametro.
Invece grazie a SetADOParameter il codice non sarà assolutamente da toccare, almeno non per quanto riguarda la creazione del parametro, e non è un risparmio da poco.

(*) E' ovvio che sarà usato sempre adParamInput, che in Access è l'unica direzione possibile, ma siete liberi di parametrizzare ulteriormente la routine indicandone la direzione qualora utilizzate database che la supportano.

 




Ora voglio parlare brevemente delle date

 

Nella prima versione del progetto abbiamo visto in dettaglio come eseguire azioni importanti come INSERT e UPDATE, ma non abbiamo ancora esaminato nel dettaglio come si imposta una SELECT.
E' pur vero che nella routine 'QueryOggiAdHoc' del modulo 'frmQuery' abbiamo utilizzato una SELECT, ma questo serviva più che altro a confrontare i due tipi di query (stored procedure e ad hoc), e l'uso era limitatamente riferito ad una selezione di intervallo di date.

Se ritenete di sapere già tutto sulle date e sul come gestirle correttamente, potete saltare questa parte.

----------------------------------------------------------------------
LE DATE: non tutte le ciambelle riescono col buco
----------------------------------------------------------------------
A tal proposito è utile soffermarci un attimo sulla questione date perchè sicuramente avrete notato come ho impostato i parametri nel definire l'intervallo di date DA... A...
Soprattutto credo che più di qualcuno si sia chiesto il perchè nel parametro A... sia stato aggiunto la parte 'ora' alla data utilizzando la stringa

23.59.59

Questo aspetto della questione sulle date è molto importante perchè spesso crea in chi non ha molta esperienza sui database una sensazione mista tra delusione ed impotenza. Veniamo al sodo.
Quando si esegue un'interrogazione del tipo:
'Dammi l'elenco di tutti gli ordini stipulati tra il 1 gennaio ed il 20 marzo'
viene logico pensare che la query debba essere costruita così:

SELECT NumeroOrdine, DataOrdine
FROM Ordini
WHERE DataOrdine BETWEEN #01/01/2008# AND #20/03/2008#

N.B.  Per semplificare la comprensione dell'argomento, sto indicano le date nel formato italiano.
Ma tenete sempre presente che nella stragrande maggioranza dei database il formato della data di default è smpre quello americano MM/DD/YYYY HH:NN:SS (se non impostato in modo diverso).
Purtroppo in un database MDB (Access) non abbiamo scampo perchè non è possibile impostare il formato dei campi Date/Time, che sarà sempre e solo americano.
Non tutti conoscono questo 'dettaglio' perchè aprendo una tabella di un database in ambiente MsAccess le data sono visualizzate nel formato italiano DD/MM/YYYY HH:NN:SS ed è facile cadere nel tranello credendo che anche nel codice VB6 vanno indicate così.
Ma così non è! MsAccess usa il formato di visualizzazione indicato nelle impostazioni regionali del sistema, quindi se abbiamo Windows in italiano, userà il formato italiano. 
Ciò nonostrante, il formato del tipo Date/Time internamente resta sempre l'americano, e da codice VB6 'deve' sempre essere formattato usando l'apposita funzione Format().
In realtà, usando i parametri di ADO, questo problema non si pone, dato che pensa lui a tutto.

Una volta eseguita la query, se andiamo a fare una verifica (spero che tutti la facciano!) scopriamo che mancano tutti gli ordini relativi all'ultimo giorno (e qui inizia lo sconcerto!).
La causa di questo è perchè non si è considerato la parte ORA pensando che la parte DATA è sufficiente.
Perchè? La risposta è semplice però non voglio fornirvela come un assunto, ma vi aiuterò ad arrivarci da soli.

Quando voi indicate l'intervallo iniziale #01/01/2008# il database in realtà interpreta questo:

#01/01/2008 0.00.00#

Perchè è ovvio che il giorno inizia dallo ore 0.00.00. Vero?
Ma così è altrettanto ovvio che un giorno termina alle 23.59.59.
Ora, se come intervallo finale voi indicate #20/03/2008# come lo interpreta il database? In base a quanto abbiamo appena capito, lo interpreterà così:

#20/03/2008 0.00.00#

Ecco perchè gli ordini dell'ultimo giorno non saranno mai inclusi nel risultato della query, semplicemente perchè avete escluso quelli stipulati dal #20/03/2008 0.00.00# al #20/03/2008 23.59.59#.
Indicando l'intervallo BETWEEN #01/01/2008# AND #20/03/2008# in realtà equivale a scrivere
BETWEEN #01/01/2008 0.00.00# AND #19/03/2008 23.59.59#
perchè dovrebbe proprio essere un caso che un ordina sia stato stipulato alle ore 0.00.00 del 20/03/2008, non trovate?


----------------------------------------------------------------------
SOLUZIONE
----------------------------------------------------------------------
Esistono due tipi di soluzioni a questo problema:

1) Includere nella proposizione WHERE anche la parte ORA, così
 WHERE DataOrdine BETWEEN #01/01/2008# AND #20/03/2008 23.59.59#

2) Chiedere al database di confrontare solo parte DATA, così
 WHERE Format(DataOrdine, 'MM/DD/YYYY') BETWEEN #01/01/2008# AND #20/03/2008#


Ricordare che, se non espressamente indicato, il motore del database considerare sempre il valore completo, esattamente come avviene per tutti gli altri campi.

Spero di aver fornito sufficienti informazioni affinchè sia possibile utilizzare in maniera soddisfacente i parametri di ADO ricordando che tali informazioni saranno utili ancor di più quando realizzerete applicazioni con i linguaggi .NET.

Saluti

 


 Print   
Copyright (c) 2002-2019 Giorgio Brausi   Terms Of Use  Privacy Statement
DotNetNuke® is copyright 2002-2019 by DotNetNuke Corporation