Оператор SQL if в предложении where для поиска в базе данных - PullRequest
14 голосов
/ 25 ноября 2008

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

Мне нужно выражение "if" в моем предложении , где , но я не могу заставить его работать. Предложение , где должно фильтровать только по ненулевым параметрам.

Вот сп

ALTER PROCEDURE spVillaGet 
-- Add the parameters for the stored procedure here
@accomodationFK int = null,
@regionFK int = null,
@arrivalDate datetime,
@numberOfNights int,
@sleeps int = null,
@priceFloor money = null,
@priceCeil money = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
select tblVillas.*, tblWeeklyPrices.price from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where 
    If @accomodationFK <> null then
        accomodationTypeFK = @accomodationFK 
     @regionFK <> null Then
        And regionFK = @regionFK 
    IF @sleeps <> null Then
        And sleeps = @sleeps 
    IF @priceFloor <> null Then
        And price >= @priceFloor And price <= @priceCeil


END

Есть идеи, как это сделать?

Ответы [ 5 ]

25 голосов
/ 25 ноября 2008
select tblVillas.*, tblWeeklyPrices.price 
from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where (@accomodationFK IS null OR accomodationTypeFK = @accomodationFK)
  AND (@regionFK IS null or regionFK = @regionFK)
  AND (@sleeps IS null OR sleeps = @sleeps)
  AND (@priceFloor IS null OR (price BETWEEN @priceFloor And @priceCeil))
0 голосов
/ 30 декабря 2009

Попробуйте поместить оператор IF вокруг всего оператора SQL. Это означает, что будет иметь один оператор SQL для каждого условия. Это сработало для меня.

0 голосов
/ 25 ноября 2008

Как вы понимаете, IF - это процедурный код в T-SQl. Его нельзя использовать в операторе вставки / обновления / удаления / выбора, его можно использовать только для определения того, какой из двух операторов вы хотите выполнить. Когда вам нужны разные возможности внутри выписки, вы можете сделать то же, что и выше, или использовать выписку CASE.

0 голосов
/ 25 ноября 2008

Мы уже много раз использовали COALESCE здесь для " динамических предложений WHERE ", о которых вы говорите.

SELECT *
FROM  vehicles
WHERE ([vin]   LIKE COALESCE(@vin, [vin])     + '%' ESCAPE '\')
  AND ([year]  LIKE COALESCE(@year, [year])   + '%' ESCAPE '\')
  AND ([make]  LIKE COALESCE(@make, [make])   + '%' ESCAPE '\')
  AND ([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')

Большая проблема возникает, хотя, если вы хотите дополнительно фильтровать столбец, который также может иметь значение NULL ... если данные в столбце null для данной строки И пользователь не вводил ничего для поиска этот столбец (так что пользовательский ввод также null), тогда эта строка даже не будет отображаться в результатах (что, если ваши фильтры являются необязательными, является некорректным поведением исключения).

Чтобы компенсировать пустые поля, вам нужно будет сделать SQL более грязным, например:

SELECT *
FROM  vehicles
WHERE (([vin]   LIKE COALESCE(@vin, [vin])     + '%' ESCAPE '\')
       OR (@vin IS NULL AND [vin] IS NULL))
  AND (([year]  LIKE COALESCE(@year, [year])   + '%' ESCAPE '\')
       OR (@year IS NULL AND [year] IS NULL))
  AND (([make]  LIKE COALESCE(@make, [make])   + '%' ESCAPE '\')
       OR (@make IS NULL AND [make] IS NULL))
  AND (([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')
       OR (@model IS NULL AND [model] IS NULL))
0 голосов
/ 25 ноября 2008

Вы также можете использовать функцию IsNull или Coalesce

Where accomodationTypeFK = IsNull(@accomodationFK, accomodationTypeFK)
    And regionFK = Coalesce(@regionFK,regionFK)
    And sleeps = IsNull(@sleeps,sleeps ) 
    And price Between IsNull(@priceFloor, Price) And IsNull(priceCeil, Price)  

Это делает то же самое, что предложение Майкла выше ...

IsNull () и Coalesce () работают более или менее одинаково, они возвращают первый ненулевой аргумент в списке, за исключением того, что iSNull допускает только 2 аргумента, а Coalesce может принимать любое число ...

http://blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...