Pergunta

Estou criando um procedimento armazenado para retornar resultados de pesquisa, onde alguns dos parâmetros são opcionais.

Eu quero um "if" no meu , onde cláusula, mas não pode fazê-lo funcionar. O , onde cláusula deve filtrar por apenas os parâmetros não nulos.

Aqui está o sp

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

Todas as idéias como fazer isso?

Foi útil?

Solução

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))

Outras dicas

Nós usamos um monte de COALESCE aqui no passado para " dinâmica cláusulas WHERE " como você está falando.

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 '\')

Um grande problema surge embora quando quiser opcionalmente filtro para uma coluna que também é anulável ... se os dados na coluna é null para uma determinada linha e que o usuário não digite nada para pesquisar por para essa coluna (para que a entrada do usuário também é null), então essa linha não vai mesmo aparecer nos resultados (que, se os seus filtros são opcionais, é um comportamento de exclusão incorreta).

A fim de compensar campos anuláveis, você acaba tendo que fazer mais confusa SQL olhando assim:

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))

Só para você entender, IF é um código processual em T-SQL. Ele canot ser usado em uma atualização instrução de inserção / / delete / select ele só pode ser usado para determinar qual das duas declarações que você deseja executar. Quando você precisar de diferentes possibilidades dentro de uma declaração, você pode fazer como acima ou usar uma instrução CASE.

Você também pode usar a função IsNull ou Coalesça

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)  

Este faz a mesma coisa que a sugestão de Michael acima ...

IsNull () e Coalesce () trabalho mais ou menos da mesma maneira, eles retornam o primeiro argumento não nulo na lista, exceto isnull permite apenas 2 argumentos, e Coalesça pode tomar qualquer número ...

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

Tente colocar sua declaração IF em torno de toda a instrução SQL. Isso significa que terá uma instrução SQL para cada condição. Que funcionou para mim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top