Discussione:
Differenze tra CDbl di Access e Convert di SQL
(troppo vecchio per rispondere)
Luca
2004-01-05 12:20:34 UTC
Permalink
Ciao a tutti,

Sto effettuando il porting di un applicativo .asp con db Access ad un db
SQL. Ho un problema con la funzione CDbl.
Ho un campo che contiene un valore double rappresentante una data. Ho
inserito questo valore tramite l'istruzione asp:

MyRs("LoginDate") = CDbl(Now)

Quando faccio le successive select, tutto funziona bene, ad esempio:

SELECT * From Users WHERE CDbl(Now) - LoginDate > 1

(questa select serve per estrarre tutti gli utenti che si sono collegati da
più di un giorno). Tutto funziona bene con Access.

Con SQL Server 2000, invece, se faccio:

SELECT * From Users WHERE Convert(float,GetDate) - LoginDate > 1

non mi ritorna nulla! Lavorandovi un po', ho scoperto che questo accade
perché le istruzioni:

CDbl(Now) --> Access
Convert(float,GetDate) --> SQL

*non* restituiscono lo stesso valore double, ma il valore SQL è
esattamente -2 del valore Access. Quindi sembra che SQL tolga sempre 2
giorni. Invece dovrebbero restituire lo stesso valore, vero? In fondo io gli
sto chiedendo di trasformarmi in double la data/ora corrente, e il risultato
dovrebbe essere sempre uguale!

Come mai? Qualcuno mi può spiegare?
Grazie!

Luca
Lorenzo Benaglia
2004-01-05 12:36:18 UTC
Permalink
Post by Luca
Come mai? Qualcuno mi può spiegare?
Ciao luca,

perché mai devi gestire le date trasformandole in un numero decimale per lo
più approssimato?!?
Sia Access che SQL Server dispongono di appositi data types per gestire le
informazioni datetime.
Il mio cosiglio è quello di rivedere la memorizzazione di queste
informazioni utilizzando gli strumenti corretti.
Per quanto riguarda SQL Server ti suggerisco la lettura del seguente tip:
http://italy.mvps.org/MVPs/lbenaglia/LorenzoBenaglia-Tip-FormatoDate.htm
Post by Luca
Grazie!
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org
Luca
2004-01-05 13:11:25 UTC
Permalink
Post by Lorenzo Benaglia
Ciao luca,
perché mai devi gestire le date trasformandole in un numero decimale per lo
più approssimato?!?
Sia Access che SQL Server dispongono di appositi data types per gestire le
informazioni datetime.
Ciao Lorenzo,

Grazie per la risposta! Lo so che non è il modo corretto (e infatti nei
nuovi applicativi .asp ho iniziato a cambiarlo), ma per questo applicativo
non posso modificare nulla perché richiederebbe troppo tempo. Devo solo
convertirlo in SQL. Per il momento tutto procede tranne questo problema (che
ho temporaneamente risolto togliendo -2, ma non so' il perché).
Grazie,

Luca
Lorenzo Benaglia
2004-01-05 14:24:23 UTC
Permalink
Post by Luca
Per il momento tutto procede
tranne questo problema (che ho temporaneamente risolto togliendo -2,
ma non so' il perché).
Ciao Luca,

facendo una ricerca su MSDN ho trovato il motivo di questa discrepanza.

In VBA le variabili Date sono memorizzate come numeri in virgola mobile di 8
bytes.
La parte intera rappresenta le date mentre quella decimale il tempo.
Le date antecedenti il 30/12/1899 saranno rappresentate da numeri negativi.
(per maggiori info:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbenlr98/html/vadatdate.asp?frame=true )

SQL Server offre due data types per la memorizzazione delle date: datetime e
smalldatetime.

datetime
--------
Range di validità: 1 gennaio 1753 - 31 dicembre 9999 con una precisione pari
a 0.00333 secondi.
Bytes occupati: 8 (2 coppie di interi di 4 bytes)
- i primi 4 per la memorizzazione dei giorni prima o dopo l'1 gennaio 1900
- gli altri 4 per la memorizzazione dei millisecondi dopo la mezzanotte

smalldatetime
-------------
Range di validità: 1 gennaio 1900 - 6 giugno 2079 con una precisione al
minuto.
Bytes occupati: 4 (2 coppie di interi di 2 bytes)
- i primi 2 per la memorizzazione dei giorni dopo l'1 gennaio 1900
- gli altri 2 per la memorizzazione dei minuti dopo la mezzanotte

In entrambi i casi la base date è 01/01/1900. Le date antecedenti la base
date saranno rappresentati da numeri negativi mentre quelle successive come
numeri positivi.

(per maggiori info:
http://msdn.microsoft.com/library/en-us/tsqlref/ts_da-db_9xut.asp?frame=true
)

Ecco spiegata la discrepanza di 2 giorni tra i due sistemi.

Esempio:

- Immediate Window di Visual basic 6.0 SP5
?cdbl(#01/05/2004 15:20:36#)
37991,6393055556

- SQL Server 2000 SP3a
SELECT CAST(CAST('20040105 15:20:36' AS datetime) AS decimal(15,10)) Data
GO

/* Output:

Data
-----------------
37989.6393055556

(1 row(s) affected)

*/
Post by Luca
Grazie,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org
Luca
2004-01-05 13:24:05 UTC
Permalink
Ciao,

Ho letto l'articolo:
http://italy.mvps.org/MVPs/lbenaglia/LorenzoBenaglia-Tip-FormatoDate.htm

Come ho già detto, nelle nuove applicazioni uso un formato differente (non
un double) e precisamente una stringa (varchar) sempre nel formato
yyyymmddhhnnss, ad esempio 20040105142207

Cosa dici? E' corretto? Oppure è meglio utilizzare quanto descritto
nell'articolo?

Grazie,

Luca
Lorenzo Benaglia
2004-01-05 13:35:36 UTC
Permalink
Post by Luca
Cosa dici? E' corretto?
Assolutamente NO!
Post by Luca
Oppure è meglio utilizzare quanto descritto
nell'articolo?
Leggi attentamente gli articoli di Kalen Delaney e capirai i pro
nell'utilizzare i data types corretti.
Post by Luca
Grazie,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org
Loading...