Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Условие сравнения по дате с возможными NULL-значениями  [new]
shanton
Member

Откуда: Украина г. Хмельницкий
Сообщений: 614
Упрощённый вариант процедуры:
CREATE PROCEDURE MyProc
	@DAT_POST DATETIME
AS
	SELECT * FROM MyTab WHERE ISNULL(dat_post, '') = ISNULL(@DAT_POST, '')

будет корректно работать?
Пробую - работает. Но я имею в виду корректность данной реализации в целом.
MSSQL 2005.
6 ноя 19, 11:39    [22010609]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6680
shanton,

если устраивает такое SELECT CAST('' as date)
6 ноя 19, 11:47    [22010618]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19586
А не проще перед запросом SET ANSI_NULLS OFF, и потом просто сравнивать?
6 ноя 19, 11:52    [22010625]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
shanton
Member

Откуда: Украина г. Хмельницкий
Сообщений: 614
Akina
А не проще перед запросом SET ANSI_NULLS OFF, и потом просто сравнивать?

В будущих версиях собираются убрать данную настройку. И не хочется изменять поведение SQL в целом, чтобы не затронуть то что уже работает.
6 ноя 19, 12:02    [22010640]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
shanton
Member

Откуда: Украина г. Хмельницкий
Сообщений: 614
TaPaK
shanton,

если устраивает такое SELECT CAST('' as date)

такое не устраивает. Но у меня пустых значений не может быть. Может быть два варианта: NULL или конкретная дата. Просто можно было написать иначе, например:
SELECT * FROM MyTab WHERE ISNULL(dat_post, 0) = ISNULL(@DAT_POST, 0)

или ещё как-то. Если разницы нет, то нечего и думать.
6 ноя 19, 12:10    [22010648]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
invm
Member

Откуда: Москва
Сообщений: 8839
shanton,

WHERE exists(select dat_post intersect select @DAT_POST)
6 ноя 19, 12:17    [22010655]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6680
shanton,

автор
Но у меня пустых значений не может быть.

конкретная дата 01/01/1900?
6 ноя 19, 12:20    [22010657]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6949
shanton,

почему нет разницы? В Вашей транскрипции невозможно использовать индексную оптимизацию.
6 ноя 19, 12:28    [22010663]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19586
shanton
В будущих версиях собираются убрать данную настройку. И не хочется изменять поведение SQL в целом, чтобы не затронуть то что уже работает.
И это при том, что данные до сих пор в 2005 версии? и при том, что, несмотря на давние обещания, до сих пор не удалено? как, впрочем, и не реализовали, и даже не пообещали, null-safe compare.

Да и при чём тут "поведение SQL в целом"? я ж вроде вменяемо сказал - OFF, запрос, обратно ON. На один запрос. А если в очередной версии уберут, и вдруг вы на неё перейдёте - так всего и делов один запрос переписать.
6 ноя 19, 13:16    [22010702]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
Akina
я ж вроде вменяемо сказал - OFF, запрос, обратно ON. На один запрос.

угу, на каждый, где есть сравнение с null = null


Akina
А если в очередной версии уберут, и вдруг вы на неё перейдёте - так всего и делов один запрос переписать.

см. выше.
6 ноя 19, 13:30    [22010713]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
Akina
shanton
В будущих версиях собираются убрать данную настройку. И не хочется изменять поведение SQL в целом, чтобы не затронуть то что уже работает.
И это при том, что данные до сих пор в 2005 версии? и при том, что, несмотря на давние обещания, до сих пор не удалено? как, впрочем, и не реализовали, и даже не пообещали, null-safe compare.

Да и при чём тут "поведение SQL в целом"? я ж вроде вменяемо сказал - OFF, запрос, обратно ON. На один запрос. А если в очередной версии уберут, и вдруг вы на неё перейдёте - так всего и делов один запрос переписать.



Да, и самое главное. В случаях индексов по вычисляемым колонкам или индексированным вью, ansi_nulls off не поможет.

В примере ниже, индекс по вычисляемой колонке dt2 не может быть использован из-за set ansi_nulls off
drop table if exists #t
create table #t (
	dt1	datetime2
	, dt2 as dt1
)

create clustered index i on #t(dt2)



declare @dt datetime2 = null


set ansi_nulls off

select *
from #t with(forceseek)
where 
	dt2 = @dt 

set ansi_nulls on
6 ноя 19, 13:50    [22010727]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19586
Ну тогда только переписывать как

CREATE PROCEDURE MyProc
	@DAT_POST DATETIME
AS
	SELECT * FROM MyTab WHERE dat_post = @DAT_POST
    UNION ALL
	SELECT * FROM MyTab WHERE dat_post IS NULL AND @DAT_POST IS NULL
6 ноя 19, 13:59    [22010738]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
Akina
Ну тогда только переписывать как

CREATE PROCEDURE MyProc
	@DAT_POST DATETIME
AS
	SELECT * FROM MyTab WHERE dat_post = @DAT_POST
    UNION ALL
	SELECT * FROM MyTab WHERE dat_post IS NULL AND @DAT_POST IS NULL


Выше же показали способ сравнивать

invm
WHERE exists(select dat_post intersect select @DAT_POST)
6 ноя 19, 14:01    [22010741]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 46887
msLex
Akina
Ну тогда только переписывать как

CREATE PROCEDURE MyProc
	@DAT_POST DATETIME
AS
	SELECT * FROM MyTab WHERE dat_post = @DAT_POST
    UNION ALL
	SELECT * FROM MyTab WHERE dat_post IS NULL AND @DAT_POST IS NULL



Выше же показали способ сравнивать

invm
WHERE exists(select dat_post intersect select @DAT_POST)

В SQL2005 ещё не было INTERSECT (если не ошибаюсь)
6 ноя 19, 14:08    [22010746]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 46887
iap
msLex
пропущено...


Выше же показали способ сравнивать

пропущено...
В SQL2005 ещё не было INTERSECT (если не ошибаюсь)
Посыпаю голову пеплом!
Ссылка на меня же меня опровергает: https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=309733&msg=2829696
6 ноя 19, 14:14    [22010749]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
shanton
Member

Откуда: Украина г. Хмельницкий
Сообщений: 614
invm

WHERE exists(select dat_post intersect select @DAT_POST)

в 2005-м работает.
6 ноя 19, 14:15    [22010750]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 46887
shanton
invm

WHERE exists(select dat_post intersect select @DAT_POST)


в 2005-м работает.
Тогда непонятно, что вам ещё нужно? И даже индексы могут использоваться, если есть.
6 ноя 19, 14:17    [22010751]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
iap
shanton
пропущено...

в 2005-м работает.
Тогда непонятно, что вам ещё нужно? И даже индексы могут использоваться, если есть.



Хмм, с вычисляемыми полями интерсект тоже не очень то работает


drop table if exists #t
create table #t (
	dt1	datetime2
	, dt2 as dt1 
)

create clustered index i on #t(dt2)



declare @dt datetime2 = null




select *
from #t with(forceseek)
where 
	exists(
		select dt2
		intersect 
		select @dt
	)


Сообщение было отредактировано: 6 ноя 19, 14:28
6 ноя 19, 14:27    [22010763]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
все чудесатее и чудесатее (с)

А так, работает

drop table if exists #t
create table #t (
	dt1	datetime
	, dt2 as cast(dt1 as datetime2)
)

create clustered index i on #t(dt2)



declare @dt datetime2 = null




select *
from #t with(forceseek)
where 
	exists(
		select dt2
		intersect 
		select @dt
	)
6 ноя 19, 14:34    [22010775]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
invm
Member

Откуда: Москва
Сообщений: 8839
msLex
все чудесатее и чудесатее (с)
Ничего чудесатого.
Просто в первом случае в предикаты подставляется dt1 вместо dt2, поэтому и не работает.
6 ноя 19, 15:08    [22010818]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
invm
msLex
все чудесатее и чудесатее (с)
Ничего чудесатого.
Просто в первом случае в предикаты подставляется dt1 вместо dt2, поэтому и не работает.

Это понятно.
Не понятно, почему в первом случае не может использовать индексированный dt2

Сообщение было отредактировано: 6 ноя 19, 15:10
6 ноя 19, 15:09    [22010823]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
invm
Member

Откуда: Москва
Сообщений: 8839
msLex
Не понятно, почему в первом случае не может использовать индексированный dt2
Индекс по dt2, а предикат по dt1. Оптимизатор сам себя обманул.
6 ноя 19, 15:15    [22010827]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
msLex
Member

Откуда:
Сообщений: 6959
invm
msLex
Не понятно, почему в первом случае не может использовать индексированный dt2
Индекс по dt2, а предикат по dt1. Оптимизатор сам себя обманул.

Так же (предикат по dt1, вместо dt2) происходит при set ansi_nulls off, но про это хоть явно указано в доке, а тут...

Хотя, может, это и не связанные вещи.
6 ноя 19, 15:23    [22010835]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
invm
Member

Откуда: Москва
Сообщений: 8839
msLex,

От настройки ansi_nulls зависит используемость индекса. А подмена столбца в предикате нет.
6 ноя 19, 15:59    [22010874]     Ответить | Цитировать Сообщить модератору
 Re: Условие сравнения по дате с возможными NULL-значениями  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 3998
shanton,

Если вас беспокоит скорость и оптимальность, то напишите

SELECT * FROM MyTab WHERE dat_post = @DAT_POST OR (dat_post IS NULL AND @DAT_POST IS NULL) 


ибо ISNULL чего-то сжирает

А вот это будет хуже

SELECT * FROM MyTab WHERE dat_post = @DAT_POST
    UNION ALL
SELECT * FROM MyTab WHERE dat_post IS NULL AND @DAT_POST IS NULL
6 ноя 19, 17:27    [22010968]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить