2009-03-11 5 views
11

j'ai rencontré un problème lié à la conversion datetimes de XML (ISO8601: aaaa-mm-jjThh: mi: SS.mmm) à SQL Server datetime 2005. Le problème est lorsque la conversion des millisecondes sont fausses. Je l'ai testé à la fois la conversion implicite et explicite à l'aide de convertir (datetime, MaDate, 126) de nvarchar, et le résultat est le même:Millisecondes mal lors de la conversion de XML en datetime SQL Server

Original    Result 
2009-10-29T15:43:12.990 2009-10-29 15:43:12.990 
2009-10-29T15:43:12.991 2009-10-29 15:43:12.990 
2009-10-29T15:43:12.992 2009-10-29 15:43:12.993 
2009-10-29T15:43:12.993 2009-10-29 15:43:12.993 
2009-10-29T15:43:12.994 2009-10-29 15:43:12.993 
2009-10-29T15:43:12.995 2009-10-29 15:43:12.997 
2009-10-29T15:43:12.996 2009-10-29 15:43:12.997 
2009-10-29T15:43:12.997 2009-10-29 15:43:12.997 
2009-10-29T15:43:12.998 2009-10-29 15:43:12.997 
2009-10-29T15:43:12.999 2009-10-29 15:43:13.000 

Mes tests non étendu montre que le dernier chiffre est soit 0, 3 ou 7. Est-ce un simple problème d'arrondi? La précision en millisecondes est importante, et perdre/gagner un ou deux n'est pas une option.

Répondre

17

Oui, SQL Server tours à temps 3.(3) millisecondes:

SELECT CAST(CAST('2009-01-01 00:00:00.000' AS DATETIME) AS BINARY(8)) 
SELECT CAST(CAST('2009-01-01 00:00:01.000' AS DATETIME) AS BINARY(8)) 

0x00009B8400000000 
0x00009B840000012C 

Comme vous pouvez le voir, ces « s diffèrent DATETIME par 1 secondes, et leurs représentations binaires diffèrent par 0x12C, qui est 300 en décimal.

En effet, SQL Server stocke la time partie du DATETIME comme un certain nombre de 1/300 secondes tiques de minuit.

Si vous voulez plus de précision, vous devez stocker une partie TIME comme une valeur distincte. Comme, le temps de magasin arrondi à une seconde comme DATETIME et millisecondes ou quelle que soit la précision dont vous avez besoin en tant INTEGER dans une autre colonne.

Cela vous permettra d'utiliser DATETIME complexes Arithmétique, comme l'ajout de mois ou de trouver des jours de la semaine sur DATETIME « s, et vous pouvez simplement ajouter ou les millisecondes et soustrayez concaténer le résultat que .XXXXXX+HH:MM pour obtenir une représentation valide XML.

+0

Quelle est la solution alors? –

+0

Je dirais, n'utilisez pas le datatyp DateTime de SQL Server. Stocker la valeur dans un VARCHAR à la place. –

+1

Merci, c'était éclairant, bien que quelque peu déprimant. – chriscena

6

En raison de la precision issues mentioned by Quassnoi si vous avez la possibilité d'utiliser l'utilisation SqlServer 2008, vous pouvez envisager d'utiliser datetime2 datatype ou si vous êtes seulement préoccupé par la partie temps, vous pouvez utiliser time datatype

Date and Time Data Types - la liste de tous les types et leur précision Dans Sql Server 2005, si j'avais besoin d'une précision de 1 milliseconde, j'ajoutais une colonne supplémentaire miliseconde de type int pour stocker le nombre de millisecondes et supprimer la partie miliseconds de la colonne dateTime (la définir sur 000). Cela supposant que vous avez besoin de l'information de la date aussi bien.

+0

Nous avons effectué des tests avec SQL Server 2008, mais le client est toujours en 2005. Des mises à niveau ont été suggérées. – chriscena

Questions connexes