Ошибка в миллисекундах при преобразовании из XML в SQL Server datetime
Я столкнулся с проблемой, связанной с преобразованием времени передачи данных из XML (ISO8601: yyyy-mm-ddThh: mi: ss.mmm) в SQL Server 2005 datetime. Проблема заключается в том, что преобразование миллисекунд неверно. Я проверил как неявное, так и явное преобразование с помощью convert (datetime, MyDate, 126) из nvarchar, и результат тот же:
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
Мое неэквивалентное тестирование показывает, что последняя цифра либо 0, либо 3, либо 7. Является ли это простой проблемой округления? Точность миллисекунд важна, и потерять / получить один или два не вариант.
2 ответа:
Да,
SQL Server
Время округления до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
DATETIME
отличаются на1
секунды, а их двоичные представления отличаются на0x12C
, то есть300
в десятичной системе счисления.Это потому, что
SQL Server
хранитtime
ЧастьDATETIME
как число1/300
вторых тиков от полуночи.Если вы хотите повысить точность, вам нужно сохранить часть
Это позволит вам использовать сложную арифметикуTIME
как отдельное значение. Например, хранить время, округленное до секунды какDATETIME
, и миллисекунды или любая точность, которая вам нужна в качествеINTEGER
в других столбцах.DATETIME
, например, добавлять месяцы или находить дни недели наDATETIME
, и вы можете просто добавить или вычесть миллисекунды и объединить результат как.XXXXXX+HH:MM
, чтобы получить действительное представлениеXML
.
Из-за проблем точности , упомянутых Quassnoi Если у вас есть возможность использовать use SqlServer 2008, Вы можете рассмотреть возможность использования datetime2 datatype или если вас интересует только временная часть, вы можете использовать time datatype
Типы данных даты и времени - перечисляет все типы и их точность
В Sql Server 2005, если бы мне требовалась точность 1 миллисекунда, я бы добавил дополнительный столбец milisecond типа int для хранения числа милисекунды и удалите часть милисекунд из столбца dateTime (установите ее в значение 000). Это при условии, что вам также нужна информация о дате.