Problema campo datetime con SQL Server 2000

mercoledì 14 dicembre 2005 - 09.15

FallenDevil Profilo | Newbie

Testando un semplice applicativo realizzato in C# mi sono accorto di un fastidiosissimo errore.
In una tabella del DB ho come campo chiave la data; al momento dell'inserimento cambia variando i millisecondi. Da premettere

La query d'inserimento è questa:

UPDATE request_queue SET state = @state WHERE request_time = CONVERT(datetime, @request_time, 121) AND place_id = @place_id


...nel parametro @request_time ho passato prima un valore DateTime formattato .ToString("yyyy-MM-dd HH\\:mm\\:ss.fff")... poi ho provato a cambiare il tipo in stringa ma il problema persiste...

...qualcuno può consigliarmi qualcosa?

Grazie in anticipo

totti240282 Profilo | Guru

e aggiungo che i parametri risolvono parecchi problemi di casting e di sicurezza,quindi usate sempre quelli.

C'è solo un capitano !!!!!!

FallenDevil Profilo | Newbie

il problema non sta nell'uso dei parametri o cos'altro... il grosso buco deriva dal fatto che al momento dell'inserimento, il valore cambia di alcuni millisecondi e non riesco a spiegarmi il perchè...

Esempio...
Inserisco 2005-12-14 12:05:14.667 nel DB mi trovo 2005-12-14 12:05:14.669

FallenDevil Profilo | Newbie

la formattazione ToString(ecc) l'ho usata solo perchè non riuscivo a capire dove fosse il problema

lbenaglia Profilo | Guru

Ciao FallenDevil,

nel primo post dicevi:

> In una tabella del DB ho come campo chiave la data; al momento dell'inserimento
> cambia variando i millisecondi. Da premettere
> La query d'inserimento è questa:
> UPDATE request_queue
> SET state = @state
> WHERE request_time = CONVERT(datetime, @request_time, 121)
> AND place_id = @place_id

Sucessivamente hai scritto:

>Inserisco 2005-12-14 12:05:14.667 nel DB mi trovo 2005-12-14
> 12:05:14.669

Il datatype datetime ha una accuratezza di 3.33 milliscecondi.
Questo significa che definire una PK su una colonna datetime è estremamente pericoloso:

USE tempdb;
GO

/* Definisco la tabella dbo.request_queue */
CREATE TABLE dbo.request_queue(
request_time datetime NOT NULL
);
GO

/* La popolo */
INSERT dbo.request_queue VALUES('20051214 12:05:14.665');
INSERT dbo.request_queue VALUES('20051214 12:05:14.666');
INSERT dbo.request_queue VALUES('20051214 12:05:14.667');
INSERT dbo.request_queue VALUES('20051214 12:05:14.668');
INSERT dbo.request_queue VALUES('20051214 12:05:14.669');
GO

/* Vediamo */
SELECT *
FROM dbo.request_queue;
GO

/* Output:

request_time
------------------------
2005-12-14 12:05:14.667
2005-12-14 12:05:14.667
2005-12-14 12:05:14.667
2005-12-14 12:05:14.667
2005-12-14 12:05:14.670

(5 row(s) affected)

*/

/* Pulizia */
DROP TABLE dbo.request_queue;


Se avessi definito una PK su request_time avrei ricevuto 3 violazioni di Primary Key e l'inserimento di sole 2 righe.
Il mio consiglio è quello di individuare una chiave naturale nella tabella e se non esiste affidarsi all'attributo IDENTITY.

Per maggiori info consulta i seguenti paragrafi sui Books Online:

"datetime and smalldatetime"
http://msdn.microsoft.com/library/en-us/tsqlref/ts_da-db_9xut.asp

"IDENTITY (Property)"
http://msdn.microsoft.com/library/en-us/tsqlref/ts_ia-iz_3iex.asp

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

FallenDevil Profilo | Newbie

...e ti ringrazio Lorenzo... purtroppo la tabella interessata ha fra i campi chiave un datetime e purtroppo non posso nemmeno cambiare la sua struttura per motivi aziendali...

...vedrò di aggirare il problema....

lbenaglia Profilo | Guru

>...e ti ringrazio Lorenzo... purtroppo la tabella interessata
>ha fra i campi chiave un datetime e purtroppo non posso nemmeno
> cambiare la sua struttura per motivi aziendali...

Ciao FallenDevil,

A poco a poco si aggiungono pezzi al puzzle :-)
Se la PK è costituita anche da altre colonne, allora il discorso cambia un po': bisogna vedere quanto sia garantita l'univocità della chiave, ma senza struttura della tabella e logica di valorizzazione dei campi non posso farmi una opinione.

Ad ogni modo stai tranquillo che se esegui una INSERT con 2005-12-14 12:05:14.667 non potrai avere nel DB 2005-12-14 12:05:14.669 ed il motivo l'ho riassunto e dimostrato nel precedente post :-)

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

FallenDevil Profilo | Newbie

>A poco a poco si aggiungono pezzi al puzzle :-)
>Se la PK è costituita anche da altre colonne, allora il discorso
>cambia un po': bisogna vedere quanto sia garantita l'univocità
>della chiave, ma senza struttura della tabella e logica di valorizzazione
>dei campi non posso farmi una opinione.
>
>Ciao!


...problema aggirato... invece di prendere la data e l'ora tramite DateTime.Now(), la prendo tramite query dal DB eliminando quindi tutti i problemi legati all'accuratezza sui millisecondi...

...mi sei stato di grande aiuto :)

lbenaglia Profilo | Guru

> ...problema aggirato... invece di prendere la data e l'ora tramite DateTime.Now(),
> la prendo tramite query dal DB eliminando quindi tutti i problemi legati
> all'accuratezza sui millisecondi...

Ciao FallenDevil,

i problemi legati all'accuratezza del data type datetime sono intrinseci al data type stesso, quindi avrai sempre una approssimazione a 3.33 milliscecondi indipendentemente da dove proviene l'informazione oraria.

> ...mi sei stato di grande aiuto :)
Mi fa piacere, anche se non ho capito come hai risolto :-)

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5