powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как объяснить программисту как правильно писать запросы
25 сообщений из 46, страница 1 из 2
Как объяснить программисту как правильно писать запросы
    #39827987
flexgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прислали мне сегодня код процедуры на проверку, и вижу я нечто вроде такого (имена переменных, полей и таблицы даны для примера):

Код: sql
1.
2.
3.
4.
5.
6.
select * from t1
where (f1 = @v1 or @v1 is not null)
and (f2 = @v2 or @v2 is not null)
and (f3 = @v3 or @v3 is not null)
and (f2 = @v4 or @v4 is not null)
and (f2 = @v5 or @v5 is not null)



Спрашиваю программиста что именно он имел ввиду написав это, получаю ответ - процедура вызывается с пятью параметрами, любой из них может получить значение NULL. Чтобы не проверять какие именно значения получены и не строить динамический SQL, пишут вот такой вот код. Может я чего-то не понимаю, но, как мне кажется, подобный код правильно работать не будет.
Допустим, переменная @v1 получила not null значение и такое значение имеется в поле f1, остальные - null. Тогда получается:
Код: sql
1.
2.
3.
4.
5.
(f1 = @v1 or @v1 is not null) = true
(f2 = @v2 or @v2 is not null) = false
(f3 = @v3 or @v3 is not null) = false
(f2 = @v4 or @v4 is not null) = false
(f2 = @v5 or @v5 is not null) = false


Соответственно, подобный запрос не вернет ничего несмотря на то, что значение первой переменной not null и это значение есть в таблице. Или я ошибаюсь?
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39827992
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flexgen,

ничего необычного в таком подходе программиста нет (если именно такая бизнес-логика),
строишь таблицу истинности (конъюнктивная {нормальная} форма) и проверяешь,
например если следовать твоему сценарию и {@v2~@v5} = null and {f2~f3} = null
то и все условия после первого f2=@v2 будут null=null , т.е. true
(максимальный индекс у f = 3, даже если ошибка - то не так важно для примера)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39827995
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
другое дело что именно в таком на T-SQL null=null вовсе не true
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39827996
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в смысле в таком .. виде (пропустил)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39827998
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
блин, вот туплю, есть-же ведь: SET ANSI_NULLS OFF
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828004
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flexgenИли я ошибаюсь?Не ошибаетесь.

Требуемое можно написать так
Код: sql
1.
2.
3.
4.
5.
6.
7.
select * from t1
where
exists(
 select f1, f2, f3, f4, f5
 intersect
 select @v1, @v2, @v3, @v4, @v5
);


При таком способе еще и индекс может быть задействован для поиска.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828007
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmflexgenСоответственно, подобный запрос не вернет ничего несмотря на то, что значение первой переменной not null и это значение есть в таблице. Или я ошибаюсь?Не ошибаетесь.не согласен (кроме как про индекс), я с горяча в панике что накосячил - уже несколько раз перепроверил
если через подмену то матемитически получится (при fn {n>1} = null и @vn {n>1} = null)


(1 = 1 or 1)
&(null = null or 0)
&(null = null or 0)
&(null = null or 0)
&(null = null or 0)

что преобразовывается в

(1 = 1 or 1) = true
&(1 or 0) = true
&(1 or 0) = true
&(1 or 0) = true
&(1 or 0) = true

откуда результат = true
т.е. при разных значениях fn (где часть = null) будет работать фильтрация
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828010
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
declare @t table (f1 int);
insert into @t values (1), (null);

declare @f1 int;

select @f1 = 1;
select * from @t where f1 = @f1 or @f1 is not null;

select @f1 = null;
select * from @t where f1 = @f1 or @f1 is not null;
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828021
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,
https://rextester.com/EMHCV18362
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
set ansi_nulls off
declare 
@v1 char(1)='a'
,@v2 char(1)=null
,@v3 char(1)=null
declare @t1 table(f1 char(1),f2 char(1),f3 char(1))
insert into @t1(f1,f2,f3)values
(null,null,null)
,(null,null,'c')
,(null,'b',null)
,(null,'b','c')
,('a',null,null)
,('a',null,'c')
,('a','b',null)
,('a','b','c')

select * from @t1
where (f1 = @v1 or @v1 is not null)
and (f2 = @v2 or @v2 is not null)
and (f3 = @v3 or @v3 is not null)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828023
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в смысле тавтология конечно но: в разных конструкциях в разных местах будет работать по разному с разными настройками
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828139
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invmflexgenИли я ошибаюсь?Не ошибаетесь.

Требуемое можно написать так
Код: sql
1.
2.
3.
4.
5.
6.
7.
select * from t1
where
exists(
 select f1, f2, f3, f4, f5
 intersect
 select @v1, @v2, @v3, @v4, @v5
);


При таком способе еще и индекс может быть задействован для поиска.
Класс какой!
Интересно, какой план даст. В любом случае, спасибо. Изящно.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828142
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv
Код: sql
1.
set ansi_nulls off

1. За такое как минимум лишают премии, а как максимум сразу увольняют - в назидание оставшимся.
2. В этом случае проверять переменные на null не требуется.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828149
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flexgenСоответственно, подобный запрос не вернет ничего несмотря на то, что значение первой переменной not null и это значение есть в таблице. Или я ошибаюсь?Не ошибаетесь
Но вы неправильно переписали запрос.
На самом деле:
Код: sql
1.
2.
3.
4.
5.
6.
select * from t1
where (f1 = @v1 or @v1 is null)
and (f2 = @v2 or @v2 is null)
and (f3 = @v3 or @v3 is null)
and (f2 = @v4 or @v4 is null)
and (f2 = @v5 or @v5 is null)


PS Удивительно, как компании случайным образом расставляют проверяющих и проверяемых :-)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828160
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgНо вы неправильно переписали запрос.Не факт.
Не сказано, что null в параметре означает исключение соответствующего столбца из фильтра.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828178
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flexgen,

в общем, как уже сказали вариант "f1 = @v1 or @v1 is not null" неправильный,
должен быть "f1 = @v1 or @v1 is null "
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828222
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StarikNavyflexgen,

в общем, как уже сказали вариант "f1 = @v1 or @v1 is not null" неправильный,
должен быть "f1 = @v1 or @v1 is null "
и в конце запроса еще и option (recompile) :)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828269
iiyama
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg,

+1 к is null
иначе запрос будет возвращать все содержимое таблицы если все исходные параметры не NULL => нет смысла проверки на равенство

invm, изящно, спасибо
Код: sql
1.
2.
3.
4.
exists(
 select f1, f2, f3, f4, f5
 intersect
 select @v1, @v2, @v3, @v4, @v5
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828271
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv
Код: sql
1.
(f1 = @v1 or @v1 is not null)



Я один не въезжаю в сакральный смысл этой конструкции?
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828290
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmflexgenИли я ошибаюсь?Не ошибаетесь.

Требуемое можно написать так
Код: sql
1.
2.
3.
4.
5.
6.
7.
select * from t1
where
exists(
 select f1, f2, f3, f4, f5
 intersect
 select @v1, @v2, @v3, @v4, @v5
);


При таком способе еще и индекс может быть задействован для поиска.
это вообще к чему? Речь идёт о том что передано 2 из 5ти переменных и надо вернуть по двум условиям.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828291
iiyama
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222,
в рамках set ansi_nulls off задача имеет смысл
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
set ansi_nulls off

declare @t table(f1 int, f2 int, f3 int, f4 int, f5 int)
declare @v1 int, @v2 int=99, @v3 int=99, @v4 int=99, @v5 int=99

insert into @t values (1,2,3,4,5),(null,3,4,5,6)

select * from @t t1
where (f1 = @v1 or @v1 is not null)
and (f2 = @v2 or @v2 is not null)
and (f3 = @v3 or @v3 is not null)
and (f2 = @v4 or @v4 is not null)
and (f2 = @v5 or @v5 is not null)
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828293
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iiyama,

авторв рамках set ansi_nulls off задача имеет смысл

в рамках психбольницы в которую попадут те кто будет искать какого же хрена....
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828309
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
select * from t1
where (f1 = @v1 or @v1 is not null)
and (f2 = @v2 or @v2 is not null)
and (f3 = @v3 or @v3 is not null)
and (f2 = @v4 or @v4 is not null)
and (f2 = @v5 or @v5 is not null)


Чушь какая-то...
Если нужно исключить параметры, которые NULL из критерия запросов, то я использую схему
Код: sql
1.
2.
3.
4.
select * from t1
where ISNULL(@v1, f1) = f1
  and ISNULL(@v2, f2) = f2
...


Косяк будет если в таблице в этих полях будет тоже NULL
Тогда чуть допилим запрос
Код: sql
1.
2.
3.
4.
select * from t1
where COALESCE(@v1, f1, 1) = COALESCE(f1, 1)
  and COALESCE(@v2, f2, 1) = COALESCE(f2, 1)
...



P.S. Сравнение NULL = NULL лучше не включать никогда.
Можно поймать огромных проблем.
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828311
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKiiyama,

авторв рамках set ansi_nulls off задача имеет смысл

в рамках психбольницы в которую попадут те кто будет искать какого же хрена....
+100 500
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828318
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
Код: sql
1.
2.
3.
4.
5.
6.
select * from t1
where (f1 = @v1 or @v1 is not null)
and (f2 = @v2 or @v2 is not null)
and (f3 = @v3 or @v3 is not null)
and (f2 = @v4 or @v4 is not null)
and (f2 = @v5 or @v5 is not null)



Чушь какая-то...
Если нужно исключить параметры, которые NULL из критерия запросов, то я использую схему
Код: sql
1.
2.
3.
4.
select * from t1
where ISNULL(@v1, f1) = f1
  and ISNULL(@v2, f2) = f2
...



Косяк будет если в таблице в этих полях будет тоже NULL
Тогда чуть допилим запрос
Код: sql
1.
2.
3.
4.
select * from t1
where COALESCE(@v1, f1, 1) = COALESCE(f1, 1)
  and COALESCE(@v2, f2, 1) = COALESCE(f2, 1)
...




P.S. Сравнение NULL = NULL лучше не включать никогда.
Можно поймать огромных проблем.

и не оставить шансов оптимизатору использовать индекс
...
Рейтинг: 0 / 0
Как объяснить программисту как правильно писать запросы
    #39828328
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex и не оставить шансов оптимизатору использовать индекс
Ну значит изначально делать правильную архитектуру.
Сейчас работаю с базой, где числовые и временнЫе данные забиты в текстовые поля...
Какой прок от оптимизатора в таких случаях?
...
Рейтинг: 0 / 0
25 сообщений из 46, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как объяснить программисту как правильно писать запросы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]