2009-03-11 15 views
11

Me he encontrado con un problema relacionado con la conversión de fechas de XML (ISO8601: aaaa-mm-ddThh: mi: ss.mmm) a SQL Server 2005 datetime. El problema es cuando la conversión de los milisegundos es incorrecta. He probado tanto la conversión implícita y explícita el uso de convertir (fecha y hora, MiFecha, 126) de nvarchar, y el resultado es el mismo:Milisegundos incorrectos al convertir de XML a SQL Server datetime

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 

Mi no extensivas pruebas muestran que el último dígito es 0, 3 o 7. ¿Es este un problema simple de redondeo? La precisión de milisegundos es importante, y perder/ganar uno o dos no es una opción.

Respuesta

17

Sí, SQL Server rondas vez en milisegundos: 3.(3)

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 

Como se puede ver, estos DATETIME 's difieren en 1 segundo, y sus representaciones binarias difieren en 0x12C, es decir 300 en decimal.

Esto es porque SQL Server almacena la parte time de la DATETIME como un número de 1/300 segundo garrapatas de la medianoche.

Si quiere más precisión, necesita almacenar una pieza TIME como un valor separado. Al igual, el tiempo de la tienda se redondea a un segundo como DATETIME y milisegundos o cualquier precisión que necesite como INTEGER en otra columna.

Esto le permite utilizar la aritmética DATETIME complejas, como la adición de meses o la búsqueda de los días de semana en DATETIME 's, y se puede simplemente añadir o restar los milisegundos y concatenar el resultado como .XXXXXX+HH:MM para obtener representación válida XML.

+0

¿Cuál es la solución entonces? –

+0

Yo diría que no use el tipo de datos DateTime de SQL Server. Almacene el valor en un VARCHAR en su lugar. –

+1

Gracias, esto fue esclarecedor, aunque algo deprimente. – chriscena

6

Debido a la precision issues mentioned by Quassnoi si usted tiene la opción de utilizar el uso SqlServer 2008 se puede considerar el uso de datetime2 datatype o si sólo está preocupado por la pieza del tiempo se puede utilizar time datatype

Date and Time Data Types - listas de todos los tipos y las de ellos exactitud

En Sql Server 2005 si necesitaba una precisión de 1 milisegundo, agregaría una columna extra de milisegundos de tipo int para almacenar el número de milisegundos y eliminar la parte milisegundos de la columna dateTime (establecerlo en 000). Eso asumiendo que usted necesita la información de la fecha también.

+0

Hemos estado haciendo pruebas con SQL Server 2008, pero el cliente todavía está en 2005. Se han sugerido actualizaciones. – chriscena

Cuestiones relacionadas