SQL instrução if na cláusula WHERE para banco de dados busca
-
11-07-2019 - |
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?
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.