множество дополнительных фильтров для сужения результатов в sql-сервере

У меня есть стол для автомобилей с этими колонками:

ID BrandID ModelID ColorID ProductionYear Price IsSecondHand . . . 

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

Я хочу написать хранимую процедуру, чтобы вернуть результаты, и я хочу найти способ написать более простой код с хорошей производительностью. Я не хочу использовать предложения 1000 if в моей процедуре.

есть идеи?

Попробуйте создать хранимую процедуру, как показано ниже.

 @BrandID INT, @ModelID INT AS SELECT Coulumns... FROM TABLE TB WHERE (@BrandID =0 OR (TB.BrandID = @BrandID )) AND (@ModelID =0 OR (TB.ModelID = @ModelID )) 

Либо вы можете сгенерировать sql из своего кода. Таким образом, вы можете поставить только необходимые условия

Обновить

Если пользователь может выбрать несколько значений для одного параметра, я предлагаю вам использовать Параметрирование предложения SQL IN или Таблично-оцененных параметров

Если запрос может зависеть от большого количества разных столбцов, для него нет хорошего одного оператора TSQL. Чтобы получить что-то вроде достойного плана выполнения, вы хотели бы, чтобы TSQL ориентировался на нужную вам комбинацию. Способ сделать это – построить SQL динамически. Теперь у вас есть 3 варианта:

  • генерировать TSQL внутри sproc и использовать sp_ExecuteSQL для его выполнения (сохраняя правильную параметризацию и повторное использование плана запроса)
  • не используйте sproc в первую очередь: сгенерируйте TSQL в C # и выполните его
  • использовать ОРМ

Первый вариант – выполнимый, но болезненный – TSQL просто на самом деле не предназначен для этого. но ты можешь сделать это. Например (сокращенно):

 declare @tsql nvarchar(4000) = 'select * from foo ...' if @name is not null set @tsql = @sql + ' and Name = @name' if @region is not null set @tsql = @sql + ' and Region = @region' -- ... exec sp_executesql @tsql, N'@name nvarchar(50), @region int`, @name, @region 

Опция C # намного проще ИМО – обычно через StringBuilder – просто добавляйте необходимые параметры и параметры.

Наконец, с ORM (в данном случае поставщиком LINQ):

 IQueryable<Foo> foos = ctx.Foos; if(name != null) foos = foos.Where(x => x.Name == name); if(region != null) foos = foos.Where(x => x.Region == region); // ... 
Interesting Posts

Избегайте взаимоблокировки для одновременного удаления

Групповые данные houly

Как восстановить базу данных Azure с помощью BACPAC во время автоматической сборки тестов?

Внутрисегментные переменные?

Как выбрать данные на основе специального условия?

Среднее число строк, в которых столбец = A в разных строках в другом столбце, сгруппированном по третьему столбцу

В спящем режиме, как программно установить уровень изоляции транзакции или как создать две транзакции с разными уровнями изоляции

SQLServerException: оператор не возвращал результирующий набор при выполнении SQL

Сохраненная процедура, которая возвращает другую таблицу по параметру

Лучший способ удалить записи в двух таблицах с внешним ключом?

Есть ли встроенная функция в sql2000, которая возвращает 0 или 0.00, если деньги или столбцы с плавающей точкой являются нулевыми?

ADO.NET: какой API я могу использовать для получения сообщения, когда SET NOCOUNT OFF

SQL Server 2008 Pivot, нет агрегирования, сложные данные

Как закодировать бит-литерал в запросе sql

Перемещение / поворот строк в столбцы и сумма

Давайте будем гением компьютера.