Разрешение даты изменения SQL в миллисекундах

#sql-server

#sql-сервер

Вопрос:

Я заметил, что дата изменения для объекта 275 в моей базе данных всегда имела конечную цифру в миллисекундах, равную 0, 3 или 7. Это выглядит как 0/3, 1/3 (округлено в меньшую сторону) и 2/3 (округлено в большую сторону).

Я написал этот запрос, чтобы проверить всю мою базу данных, и это правда:

 with a as (
select name,type_desc,modify_date, 
convert(int,DATEPART(MS,modify_date)) Mils
from sys.objects
),
 
b as (
select *,
RIGHT(Mils,1) rm
from a)
 
select * from b
order by rm
  

Я не буду перечислять все 275 строк, но все они равны 0, 3 или 7.

Мне интересно понять, что может привести к тому, что это время будет с точностью не более 3 миллисекунд?

Комментарии:

1. Это известный элемент точности в datetime. вы всегда можете перейти к datetime2, чтобы определить и повысить точность

Ответ №1:

datetime с точностью до 1/300 секунды. Это также задокументировано.

Поскольку 1/300-е округляется, тогда 0.0000000 будет отображаться как 0.000 , 0.003333333333 как 0.003 и, наконец 0.00666666666666 , и 0.007 .

Если вам нужна более высокая точность (скажем, до 1/1000 секунды), вам нужно будет использовать более новый datetime2 тип данных и присвоить ему точность 3 ( datetime2(3) ) . Однако любые существующие значения сохранят существующие значения.

Если вы достигнете еще большей точности (скажем datetime2(7) ) и измените существующий столбец на этот тип данных, то в зависимости от того, какую версию вы используете, вы получите разные результаты. В более новых версиях datetime значение 2020-09-24T17:14:01.003 будет преобразовано в 2020-09-24T17:14:01.0033333 однако в более старых версиях 2020-09-24T17:14:01.0030000 . Это то, что вы должны иметь в виду.

Ответ №2:

Если я правильно вас понял, вы хотите получить последнюю десятичную цифру из миллисекундного компонента вашего datetime .

Если это так, вы можете использовать datepart() арифметику and следующим образом:

 datepart(ms, modify_date) - datepart(ms, modify_date) / 10 * 10
  

Вот упрощенная демонстрация:

 declare @modify_date datetime2 = getdate();
select @modify_date original, 
    datepart(ms, @modify_date) ms, 
    datepart(ms, @modify_date) - datepart(ms, @modify_date) / 10 * 10 result

original                    |  ms | result
:-------------------------- | --: | -----:
2020-09-24 17:11:36.3733333 | 373 |      3

  

Комментарии:

1. Спасибо. Я собирался использовать что-то вроде этого, но затем решил сделать это в виде строки. На полпути был этот неудачный код «химеры», но, похоже, он работал, поэтому я сохранил его!