2009-03-11 2 views
11

У меня возникла проблема, связанная с преобразованием datetime из XML (ISO8601: yyyy-mm-ddThh: mi: ss.mmm) в дату и время SQL Server 2005. Проблема в том, что преобразование миллисекунд неверно. Я проверил как неявное и явное преобразование с помощью преобразования (DateTime, MyDate, 126) из NVARCHAR, а результат тот же:Неправильные миллисекунды при преобразовании из XML в 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 

Моя неэкстенсивная тестирование показывает, что последняя цифра либо 0, 3 или 7. Является ли это простой проблемой округления? Вариация Millisecond важна, и потеря/выигрыш один или два не является вариантом.

ответ

17

Да, 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 «s отличаются 1 секунды, и их двоичные представления различаются 0x12C, то есть в десятичной системе 300.

Это потому, что SQL Server хранит time части из DATETIME как число 1/300 вторых клещи с полуночи.

Если вы хотите больше точности, вам нужно сохранить часть TIME как отдельное значение. Например, время хранения округляется до секунды как DATETIME, и миллисекунды или любая точность, которую вам нужно как INTEGER в других столбцах.

Это позволит использовать сложные DATETIME арифметику, как добавление месяцев или дней недели нахождения на DATETIME-х годах, и вы можете просто добавить или вычесть миллисекунды и сцепить результат как .XXXXXX+HH:MM, чтобы получить действительное XML представление.

+0

Какое решение тогда? –

+0

Я бы сказал, не используйте Datatyp DateTime SQL Server. Вместо этого сохраните значение в VARCHAR. –

+1

Спасибо, это было поучительно, хотя и несколько удручающе. – chriscena

6

Из-за precision issues mentioned by Quassnoi, если у вас есть возможность использовать использование SqlServer 2008 вы можете рассмотреть возможность использования datetime2 datatype или если вы беспокоитесь только о части времени вы можете использовать time datatype

Date and Time Data Types - перечисляет все типы и ихнюю точность

В Sql Server 2005, если бы мне нужна точность 1 миллисекунды, я бы добавил дополнительный столбец milisecond типа int, чтобы сохранить количество миллисекунд и удалить часть miliseconds из столбца dateTime (установите его на 000). Это предполагает, что вам нужна информация о дате.

+0

Мы проводили тесты с SQL Server 2008, но клиент все еще в 2005 году. Было предложено обновление. – chriscena

Смежные вопросы