Newsgroup: it.comp.lang.visual-basic
Titolo: Errore sql sulla data

Ciao a tutto il NG
ho un problema:
in un database access memorizzo la data in un campo date/time di nome
"MiaData".
Quando leggo il database metto in una combo il contenuto del campo
MiaData come segue:
If (Not rs.EOF) Then
   rs.MoveFirst
   While Not rs.EOF
        combo_Data.AddItem rs.Fields("MiaData").Value
        rs.MoveNext
   Wend
End If
combo_Data.Text = combo_Data.List(0)
poi quando devo interrogare il database faccio una query del tipo:
"SELECT MiaData FROM Tabella GROUP BY MiaData HAVING Data >= #" &
combo_Data.Text & "# ORDER BY MiaData"
Con le "Impostazioni internazionali" su Italian(Italy) o English(United
Sates)i formati data/ora vengono riconosciuti e tutto va bene, ma se
setto le "Impostazioni internazionali" su Italian(Switzerland) il
formato data/ora nel mio database diventa: "31.03.2004"  e l'esecuzione
del programma mi dice: Errore di runtime '3075'. Errore di sintassi
nella query ......
Chiedo il vostro aiuto, non so piů cosa provare.
Grazie a tutti.
tomas
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG


C'č un post di oggi, dove se ne č parlato......
ciaociao

 "31.03.2004"
Questo č uno dei fraintendimenti piů diffusi.
Il formato data del database č uno ed uno solo, ed č un formato binario che
a te non deve interessare.
Poi, esiste un formato che ogni database accetta all'interno delle
istruzioni sql. Questo formato č 'yyyymmdd hh.mm.ss' per quasi tutti i dbms,
e #mm/dd/yyyy# per Access.
Quindi, indipendentemente dalle impostazioni internazionali del tuo PC e/o
del pc del server dbms, nelle istruzioni sql tu devi concatenare il formato
apposito.
Il problema che tu ti ritrovi, perň, nasce anche dal fatto che tu fai #" &
combo_Data.Text & "#, ossia concateni un text.
Questo č corretto dal punto di vista della tipizzazione, ma complesso da
gestire dal punto di vista del dato contenuto.
Infatti, per essere a prova di localizzazione, tu dovresti fare:
"#" & format$(Variabile_Data,"mm/dd/yyyy") & "#"
Ma tu non hai una variabile data, bensě un Text.
Quindi, prima del format$, dovresti fare un CDate in una variabile data. E
qui sei esposto al fatto che CDate č sensibile alle impostazioni
internazionali. Perň, se hai caricato il Combo usando una conversione
localizzata (e combo_Data.AddItem rs.Fields("MiaData").Value č un CStr
implicito, quindi localizzato), teoricamente sei in una operazione
reversibile e tutto dovrebbe andare.
Ciao
Alberto

 combo_Data.Text & "# ORDER BY MiaData"
La data deve essere (per Access) nel formato #MM/GG/AAAA#
Quindi devi traturre/formattare quel che ti arriva da combo_Data.Text


SELECT MiaData FROM Tabella GROUP BY MiaData HAVING Data >=  Datevalue('" &
combo_Data.Text & "')  ORDER BY MiaData"
Attenzione agli apici, Datevalue('data')
Questa funzione converte il formato impostato in windows con quello del
motore del database.
Saluti
Giovanni Chieli

Funziona!!
Grazie Giovanni. Buona serata.



Interessante.
Ovviamente vale solo per motori client-side, come Jet, ma per mia curiosità
mi chiedo: in Access, non è possibile impostare una localizzazione del db
diversa da quella del S.O.?
Perchè, se così fosse, anche il datevalue potrebbe fallire...
Scusate la domanda gnocca, ma non è che usi molto Access...
Ciao
Alberto

 e #mm/dd/yyyy# per Access.
e probabilmente è proprio questo il punto: in realtà le tabelle a cui
devo accedere sono in DBase IV, ma per mia comodità di visualizzazione
faccio un collegamento alle tabelle attraverso Access. Mi sembra di
capire, quindi, che il formato data/ora in realtà non è lo stesso che io
visualizzo in Access e che cambia tutte le volte che cambio le
impostazioni internazionali. Scusami, mea culpa per non aver dettagliato
fino in fondo il problema. Ad ogni modo, con la soluzione consigliatami
da Giovanni sembra funzionare tutto correttamente.
Ancora un GRAZIE per l'aiuto e i consigli. Ciao.


 Perchè, se così fosse, anche il datevalue potrebbe fallire...
Io non lo so se si possa impostare quanto dici (io non l'ho mai fatto), ma
il DateValue non mi convince affatto.
Resto dell'avviso che tutto dipende da quanto c'è (anzi, cosa c'è) in
combo_Data.Text e dalle localizzazioni.
Sarebbe interessante sapere, nella prova che ora si dice funzioni, qual era
la data nel combo e, ripeto, com'era scritta.

La data deve essere (per Access) nel formato #MM/GG/AAAA#
Se non ricordo male, ho letto che accetta anche le date in formato
ISO, per cui #AAAA-MM-GG#
E con questo formato vai sempre sul sicuro (a parte la rottura di
scatole di dover rifare il formato).
Con SQL Server e' quasi obbligatorio usare la data ISO o usare la
funzione CONVERT.
Ciao!
Luca
PS. A proposito di Spam.... sapessi quante mail i arrivano di gente
che mi vuol vendere il Cialis.... ;-)

 la data nel combo e, ripeto, com'era scritta.
Con le "Impostazioni internazionali" su:
Italian(Italy) combo_Data.Text = "31/03/2004"
English(UnitedSates) combo_Data.Text = "3/31/2004"
Italian(Switzerland) combo_Data.Text = "31.03.2004"
Non so cosa dire, l'argomento è sicuramente interessante...
Diao Lupo, grazie.


 che mi vuol vendere il Cialis.... ;-)
Ehhhh?! Cusalè el Cialis?

 Non so cosa dire, l'argomento è sicuramente interessante...
Interessante? Ma quando mai?! Avrebbero potuto dire un formato solo,
qualsiasi, valido per tutto il mondo e per tutti i tipi di database. Han
fatto il solito casino, altro che interessante. <eg>
Ok, non è solo colpa di M$, mapperò...

 Ok, non è solo colpa di M$, mapperò...
Hai assolutamente ragione! Comunque il mio "interessante" era riferito
alla discussione che si è sviluppata su questo problema e come
eventualmente risolverlo una volta per tutte. Certo se ci fosse sto uno
standard comune a tutti...


 standard comune a tutti...
E' vero, il casino con le date ormai l' hanno fatto ma in ogni nazione gli
utenti vogliono mantenere le loro abitudini locali, quindi il problema è
garantire che se l' utente inserisce la data secondo i suoi costumi, il
database la recepisca correttamente e Datevalue lo garantisce.
g.c:

 solito errore.
Io intendevo usando DateValue...


A me in generale non piace risolvere un problema con cose troppo specifiche
di quel singolo caso.
Cerco sempre di utilizzare metodiche che mi consentano una certa
flessibilità.
Utilizzando il Format$ di Vb, per passare da un db ad un altro devo
semplicemente cambiare la formattazione.
Utilizzando il datevalue, per passare da Access a Sql-Server, ad esempio,
devo riconcepire una parte del mio codice, perchè devo aggiungere una
formattazione che prima non c'era, e togliere il datevalue dalla sintassi
Sql.
Aggiungo, inoltre, che per utilizzare datevalue si è obbligati a rispettare
le impostazioni locali, mentre per molte applicazioni (e qui mi sovviene un
thread spaventoso di molti mesi fa), può essere necessaria una
rappresentazione indipendente dalle impostazioni internazionali.
In sostanza, il datevalue consente di risolvere questo caso specifico,
mentre il Format$ risolve TUTTI i casi di interazione coi db dove ci siano
date.
Se consideriamo che anche a livello di performance potrebbe esserci
differenza, torno a consigliare il Format$.
Ciao
Alberto

Ehhhh?! Cusalè el Cialis?
Un successore del Viagra.
Ciao!
Luca


Anch'io uso il Format$ ma ho riscontrato un problema e non so se è capitato
anche a altri.
Se sulle impostazioni internazionali come separatore delle ore ho il  " . "
(punto) e nella stringa di formattazione io inserisco il " : "  (duepunti)
ad esempio "YYYY-MM-DD HH:mm:ss" nel risultato l'ora utilizza ancora il
punto e di conseguenza mi ritorna un errore sull'SQL.

[Colonna Walter = circa_walcol[cinque]@
tin.it
 in
Qrhbc.10551$
rM4.3...@news4.tin.it
] ha scritto:

Lungi da me dal dire "fidatevi", ma non capisco questa ostinazione nel
cercare formati alternativi, presunti-funzionanti, quando ci sono quelli
"indicati" dalle guide, in particolare per Access.
PS: Io non uso, mai!, il Format quando siano coinvolti separatori. Piuttosto
uso delle mie Function che, anche se impiegano 10 volte tanto (ma non si
fanno sentire), fanno sempre quel che voglio io e "fissamente",
indipendentemente (quando è, IMHO, necessario), dalle impostazioni di
sistema.

 Io intendevo usando DateValue...
Ciao Lupo,
ho fatto ancora delle prove usando DateValue come mi hai suggerito (e
prima non avevo capito) e mi sembra che tutto ritorni regolarmente. Ho
provato ad inserire diverse date con diversi Regional Settings ma me le
ha sempre interpretate correttamente, e quando cambio i settaggi in
regional settings, le date nel database si edeguano automaticamente alla
nuova configurazione.


 sistema.
Mi sono creato anch'io Function per la gestione delle stringhe e dei
numeri dei miei database, ma non sono riuscito a creare una Function per
gestire la data indipendentemente dalle impostazioni di sistema. Mi
vergogno a dirlo ma riesco solo se memorizzo la data come stringa... :-(


 stringa... :-(
Per le Where:
Access (DAO o ADO), senza apicini:        #MM/GG/AAAA#
SQL Server (ADO), con apicini:                'AAAAMMGG'
Per il deposito (Access e SQL Server):
rs!campo_date = DateSerial(anno, mese, giorno)

 alla nuova configurazione.
Bene, meglio cosě, mai io continuo a usare quanto detto nel post sopra di
poco fa. Mai avuto problemi.
L'unico problema č il test per 0 (non Null che č un'altra cosa) di un campo
di tipo date in SQL Server: La data contenuta, pur avendo depositato 0, č
pari al 31-12-1899.

 depositato 0, è pari al 31-12-1899.
Pardon: 30-12-1899

> automaticamente alla nuova configurazione.
No! Le date nel database (come ogni altro tipo di campo) non si adeguano
mai, e ci mancherebbe pure...
E' la forma di rappresentazione che può cambiare, ma le informazioni nel
database non cambiano. In particolare, le date vengono mantenute con un
numero.
Se i campi si adeguassero nel database, lo stesso non sarebbe utilizzabile
su un'altra macchina (o la stessa) con localizzazione diversa.

 mai, e ci mancherebbe pure...
Hai ragione, dopo tutto è anche logico e basta rifletterci un attimo per
capirlo!
Ti ringrazio Lupo, ti ringrazio per la pazienza e per le PREZIOSE
informazioni e consigli.
Un grande saluto.
tomas (come te OrmaiRottoDaSpam)


 rs!campo_date = DateSerial(anno, mese, giorno)
Vuoi sapere l'ultima? Alla fine l'errore non era nella query SQL, ma
nella memorizzazione del dato!
Invece di usare:
      rs!campo_date = DateSerial(anno, mese, giorno)
facevo semplicemente:
      rs!campo_date = Now()
quando ho visto le istruzioni che hai scritto tu, ho avuto l'atroce
sospetto, ho modificato e adesso funziona tutto benissimo!!!
Mi scuso per essere stato cosě imbecille ma ti ringrazio davvero tanto.


 sospetto, ho modificato e adesso funziona tutto benissimo!!!
Ho ancora un dubbio: ero convinto che la DateSerial rendesse un numero e
non, come pur la guida specifica, un Variant di tipo date. Now è la stessa
cosa..., ma comprende anche l'ora...
In altre parole, tenuto conto del fatto che un campo date può contenere
anche un'ora, tutto dovrebbe essere compatibile (DateSerial e anche Date),
... sicuro che, trovando dentro anche l'ora (depositando Now) poi i vari
test e/o Where su tale campo fossero adeguati?


Non ho ben capito cosa intendi dire ma :
1) le date nel programma le ho sempre gestite con variabili di tipo "date",
 quindi lavorando con i recordset (rst!campodata.value=varData) non ho
nessun
 problema qualsiasi sia il db o la localizzazione dei PC;
2) quando prelevo il valore dal db per visualizzarlo allora utilizzo il
formato
 localizzato che l'utente (o chi per lui) ha impostato sul PC;
3) quando devo inserire invece il valore di una data in una istruzione SQL
allora
 li c'è il problema perché cambiando DB può cambiare la rappresentazione;
 perciò  ho impostato in un file di configurazione esterno una stringa per
gestire
 il format delle date come richieste dal motore (#MM/DD/YYYY# per
 Access, 'YYYYMMDD' per SQL Server);
4) quando ho dovuto interfacciare la procedura con DB2, se non indicavo
anche la
 parte dell'ora, mi andava in errore ed è così che ho scoperto l'anomalia
che ho segnalato
 nel mio post e cioè "se il separatore impostato è il punto, mettendo nel
formato il
 duepunti, la stringa risultato contiene comunque il punto".
Visto che si stava parlando di formati data e compatibilità mi sembrava una
annotazione utile.

  duepunti, la stringa risultato contiene comunque il punto".
Non è una anomalia.
Il carattere : (due punti), che metti nella stringa di formato, è in realtà
un carattere jolly che significa "metti qui in mezzo il separatore previsto
localmente". E' una sfiga, perchè in realtà accade che si voglia proprio il
due-punti, come separatore. E la sfiga è doppia, perchè non è detto che sia
il punto il separatore locale (è personalizzabile), per cui anche il
Replace$ con un Format$ non è la soluzione.
Occorre necessariamente reperire il carattere di separazione impostato
localmente, e poi fare il replace$ di questo con il due punti.
Non va fatto ogni volta, basta crearsi una funzioncina da chiamare
sistematicamente ogni volta che ci sia un orario da inviare al db.
Per reperire il separatore locale, alcuni tendono ad usare le api, cosa che
ovviamente sconsiglio, perchè ci si auto-castra la portabilità del sw.
Basa infatti formattare un orario come 11.11 in formato 24h, sostituire gli
uno con vbnullstring, e prendere ciò che resta (e questa metodica è usabile
anche per il separatore dei decimali, ecc...).
Ciao
Alberto


In effetti hai ragione i ":" per l'ora, come la "/" per la data, vengono
interpreti come richiesta del separatore di default e quindi convertito nel
carattere impostato sul pannello di controllo.
A questo punto basta anteporre la barra rovesciata "\" al carattere voluto
così che questo non sia mai interpretato. ("HH\:mm\:ss" ritorna sempre l'ora
con i ":" senza considerare le impostazioni internazionali)
Grazie.
Walter