powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Select с переменным количеством в WHERE
22 сообщений из 22, страница 1 из 1
Select с переменным количеством в WHERE
    #32053732
новичок
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, вот недавно видел ответ на мой вопрос, но найти через Поиск не смог. Вопрос в следующем, как в зависимости от переданных значений выбирать одним запросом, т.е.
1) если @id1 IS NULL AND id2 IS NULL - все записи
2) @id2 IS NULL - только c указанным Id1
3) @id1 IS NULL - только c указанным Id2
4) только c указанными Id1 и id2

CREATE PROCEDURE [dbo].[p_get]
@id1 INT = NULL,
@id2 INT = NULL
AS
SET NOCOUNT ON

SELECT FROM tbl WHERE id1=@id1 AND id2=@id2
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053737
Фотография Alexes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE PROCEDURE [dbo].[p_get] 
@id1 INT = NULL, 
@id2 INT = NULL 
AS 
SET NOCOUNT ON 

SELECT FROM tbl WHERE (id1=@id1 or @id1 is null) AND (id2=@id2 or @id2 is null)
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053738
новичокс
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спасиб!
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053747
fima
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Alexes Ваш запрос не будет работать т.к. Ваше условие
Код: plaintext
WHERE (id1=@id1 or @id1 is null) AND (id2=@id2 or @id2 is null)

означает выбирать записи где id1 равно значению или id1 нулевое и где id2 равно значению или id2 нулевое.
Т.е. если оба параметра нулевые, то записей в выборке не будет, т.к. id обычно нулевыми не делают

2новичок Я в таких случаях пишу три запроса и исполняю в зависимости от переданных значений. При больших количествах входных параметрах, например штук 6, количество вариантов становится равным факториал 6 и написать это трудно :). Выход из этой ситуации, динамический запрос. Но так как штука эта весьма специфичная, то я просто говорю нашим программистам чтоб интерфейс программы меняли.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053755
Фотография akuz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 fima в защиту Alexes
Посмотрите внимательнее, перед id1 и id2 в запросе стоят такие маленькие значёчки @ , что говорит о том, что на нулл проверяются не ключи а параметры процедуры.

А вот советовать программистам менять интерфейс программы, лишь потому, что вам трудно написать запрос, не советую, могут сгоряча и побить :)
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053757
fima
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приношу извинения Alexes, и правда ведь работает, а я вот не додумался до такого, снимаю шляпу :)).
А воевать с прикадниками уже привычно :)) то номера строк им выводи, то процедуру с переменным числом параметров...
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053758
Guinness
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 fima
В случае переменного числа параметров можно также воспользоваться техникой, описанной Alexes
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053849
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я об этом подробно писал, но тоже не нашел по "поиску"

Вместо CASE лучше использовать

Where field=isnull(@param,field) ...
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053913
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот, предполагаемое FAQ
/*

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

Приведенная ниже процедура делает отбор по следующим критериям:
pubdate больше или равно @pubdateStart;
pubdate меньше или равно pubdateEnd;
в title содержится строка @title;
price больше или равно @price;
ytd_sales равно @ytd_sales;

Для сравнения дат используются минимально и максимально возможные значения DateTime.
Предполагается, что поле Price не может быть меньше нуля. В реальной программе это может быть и другая константа. В дюбом случае можно использовать минимальное или максимальное значение для выбранного типа данных.
*/
--Начало кода
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
use pubs
go
create procedure test 
@pubdateStart datetime=null, @pubdateEnd datetime=null,
@title varchar( 80 )=null,
@price money=null,
@ytd_sales int=null
as 
select pubdate,title,price,ytd_sales from titles
where pubdate between isnull(@pubdateStart,'17530101') and isnull(@pubdateEnd,'99991231')
and title like '%'+isnull(@title,'')+'%'
and price>=isnull(@price, 0 )
and ytd_sales=isnull(@ytd_sales,ytd_sales)
order by pubdate,title,price,ytd_sales
go
exec test 

exec test '19910610'
exec test null,'19910630'
exec test '19910610','19910630'
exec test '19910610','19910630','t'
exec test '19910610','19910630','t', 3 
exec test '19910610','19910630','t', 3 , 3336 
exec test null,null,null,null, 3336 

drop procedure test 
--Конец кода
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053965
ura
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Cat2 : Я бы все-таки посоветовал использовать конструкцию
Код: plaintext
1.
 (id=@Id or @Id is NULL)

вместо
Код: plaintext
1.
(id=IsNull(@Id,id).

Действительно, во втором случае будет использован индекс на id, но у меня, например, тестирование показало, что первый вариант в большинстве случаев быстрее. Хотя лучше всего взять реальные данные и протестировать
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053967
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для ura.
Может быть. Действительно, только опыт является критерием истины.

У меня всегда быстрее отрабатывает isNULL

Факу я написал
Наверное надо это туда добавить.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32053991
lvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lvv
Гость
Поднимал я уже эту проблему, оба решения имеют недостатки. В любом случае индекс будет использоваться. Только план выполнения запроса чаще будет на оптимальным. Скорее всего быстрее будет динамический запрос. Предлагаю подискутировать на эту тему.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054235
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-дискутировать, конечно можно, но только есть ли смысл? Разумееется, на одних наборах данных быстрее будет одно, а на других - другое. Вряд ли удасться дать совет, вроде "При числе записей более 100000, полей больше 10 и таблиц больше 5 используйте то-то, а если таблиц больше 10 - то-то".
А вот в факу решение с динамиком внести надо.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054270
lvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lvv
Гость
В том то и вопрос, что для 2 параметров и 1000 строк в таблице может и не важно. А вот если критереев поиска около 10 и строк в таблице под 1000 000. Тут действительно сложно сказать, но думаю динамический запрос побыстрее будет. Хотя надо на практике проверить.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054622
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для lvv. Тута столько тестов провести надо, на разных таблах, что волосы дыбом встают. Да и на одной вариантов тьма. Я так думаю, что если полей много, а в отборе обычно участвует 2-3, то лучше справится динамик, а если из 20 в отборе задействуются 18, то скорее всего дело свдется к пошлому сканированию во всех вариантах. Да и с проектированием индексов тоже всякие проблемы. Если база редкоизменяемая, то хоть по всем полям индексы строй, а если это реалтайм диагностический комплекс с сотней датчиков? Нет, надо конкретную таблу смотреть, да еще хорошо бы статистику знать, какие поля при отборе самые популярные.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054672
lvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lvv
Гость
Для Cat2
Согласен, но обычно у меня такая задача возникает в различных формах поиска и тогда в запросе не одна таблица. Например таблица адресов
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Задача найти адрес
Таблица Адрес состоит из полей Код, Код города, Улица, Дом
Таблица Город: Код, Код Страны, Код Региона, Код Района, Название
Таблица Страны : Код, Название
Таблица Регионы : Код, Название
Таблица Районы : Код, Название

Искать адрес можно по фрагменту названия улицы,
по городу, по стране, по региону, по району
Может быть указан как один критерий поиска из перечисленных, так и все
 

Как тогда в таком случае поступать?
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054725
Фотография Nickolay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть у меня одна процедурка которая принимает на вход 4 параметра каждый из которых может быть нулевым. По этим параметрам строится запрос, при этом каждый параметр ставит условие на 4 колонки со связкой по ИЛИ. Я использовал динамический запрос, но прочтя этот топик решил проэксперементировать с ISNULL. Так вот динамика работает в среднем на 15% быстрее, хотя код во втором случае гораздо меньше да и читается лучше. Вот вам и результат теста. База небольшая ~ 25000 записей, индексы не используются.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054750
Фотография akuz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ простой.
Если ваша модель безопасности позволяет использовать динамический запрос - используйте!
Если же доступ к таблицам закрыт от пользователя, то вариант (для ленивых :) один - джойн по всем таблицам, которые могут появиться в условии и вере по условиям в виде (id=@Id or @Id is NULL) или (id=IsNull(@Id,id)). Хотя есть ещё вариант предлагаемый fima, использовать статические запросы в процедуре, но тогда кол-во вариантов становится равным факториал кол-ва параметров что не радует. Хотя если его слегка модифирировать и применить средство для автоматической генерации запросов то он может тоже быть интересен.
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054760
lvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lvv
Гость
Для Nickolay, согласен что менее красиво. А индексы не использовать все же не хорошо :))
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054762
lvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lvv
Гость
Для akuz
Есть проблема с безопасностью, можно попробовать обойти эту проблему создаваю View по таблице и на нее уже навешивать права
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054789
Фотография Nickolay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2lw: индексов не использую потому что это View на уже работающей базе, а для создания индексированного View надо бы базу пересоздать :(
...
Рейтинг: 0 / 0
Select с переменным количеством в WHERE
    #32054824
Фотография akuz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 lw
В моей модели безопасности пользователи имеют права только на запуск процедур...
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Select с переменным количеством в WHERE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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