Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Select с переменным количеством в WHERE / 22 сообщений из 22, страница 1 из 1
27.09.2002, 15:45:14
    #32053732
новичок
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
Прошу прощения, вот недавно видел ответ на мой вопрос, но найти через Поиск не смог. Вопрос в следующем, как в зависимости от переданных значений выбирать одним запросом, т.е.
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
27.09.2002, 15:49:16
    #32053737
Alexes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
Код: 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
27.09.2002, 15:51:32
    #32053738
новичокс
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
спасиб!
...
Рейтинг: 0 / 0
27.09.2002, 16:03:56
    #32053747
fima
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
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
27.09.2002, 16:14:04
    #32053755
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
2 fima в защиту Alexes
Посмотрите внимательнее, перед id1 и id2 в запросе стоят такие маленькие значёчки @ , что говорит о том, что на нулл проверяются не ключи а параметры процедуры.

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

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

Where field=isnull(@param,field) ...
...
Рейтинг: 0 / 0
28.09.2002, 19:18:22
    #32053913
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
Вот, предполагаемое 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
29.09.2002, 23:10:27
    #32053965
ura
ura
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Select с переменным количеством в WHERE
To Cat2 : Я бы все-таки посоветовал использовать конструкцию
Код: plaintext
1.
 (id=@Id or @Id is NULL)

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

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

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

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

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

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


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