У меня есть следующая таблица:

create table #temp_1234
(
    field1 varchar(50) null,
    field2 datetime null,
    field3 smalldatetime null
)

И, скажем, вставляю в него следующую строку:

insert into #temp_1234
(field1, field2, field3)
values ('Val1','2016-09-16 23:59:59.000',NULL)

Если я выполню запрос

select field2 from #temp_1234

В результате я получаю « 2016-09-16 23: 59: 59.000 ».


Но когда я выполняю запрос

select ISNULL(field3,field2)  from #temp_1234

Результат оказывается " 2016-09-17 00:00:00 ".


Как получается, что даже если в обоих запросах возвращается один и тот же столбец, результат в обоих случаях отличается?

Я понимаю, что smalldatetime - с точностью до минуты, а datetime - с точностью до секунды. Но как введение нулевой проверки влияет на точность возвращаемого результата?

0
Scrooge McD 7 Сен 2016 в 01:13

3 ответа

Лучший ответ

ISNULL использует два параметра: check_expression и replacement_value. Как указано в документации для replacement_value:

Выражение, которое должно быть возвращено, если check_expression имеет значение NULL. значение replace_value должно иметь тип, который неявно преобразуется в тип check_expresssion.

По сути, механизм SQL-запросов неявно преобразует значения для сравнения. Datetime имеет точность 3,33 мс, что, скорее всего, составляет округление.

Если вы хотите получить больший контроль над преобразованием, рассмотрите возможность использования явных преобразований например CAST или CONVERT.

Это также может быть хорошим вариантом использования функции COALESCE, а не ISNULL.

3
SqlOnly 6 Сен 2016 в 22:40
select ISNULL(field3,field2)  from #temp_1234

Когда вы завершаете вышеуказанный запрос, значение «field2» преобразуется в тип smalldatetime, поскольку тип данных field3 - smalldatetime. Вот почему ISNULL возвращает другое значение. Чтобы проверить, вы можете выполнить следующий запрос:

select cast(field2 as smalldatetime) from #temp_1234

В smalldatetime секция секунд всегда равна нулю (00). если значение datetime имеет секунды больше или равно 30, то к результирующему значению smalldatetime добавляется 1 минута, а секунды устанавливаются на ноль. Для секунд меньше 30 результирующее значение smalldatetime имеет часть секунд, установленную на 00, и минутную часть, как и раньше.

В вашем случае значение datetime: '2016-09-16 23: 59: 59.000'. Поскольку секция секунд значения datetime больше 30, поэтому к результирующему значению smalldatetime добавляется 1 минута, которая дает значение: '2016-09-17 00:00:00'.

0
Akshey Bhat 7 Сен 2016 в 05:54

Isnull преобразует второе значение в формат первого значения.

Это еще яснее:

Объявить дату @date, @datetime datetime = getdate () выбрать isnull (@date, @datetime)

0
Manuela Re 6 Сен 2016 в 22:45