SQL si instruction dans la clause where pour la recherche dans la base de données
-
11-07-2019 - |
Question
Je crée une procédure stockée pour renvoyer les résultats de la recherche dans lesquels certains paramètres sont facultatifs.
Je souhaite une déclaration "if" " dans ma où clause mais je ne peux pas le faire fonctionner. La clause où ne doit filtrer que les paramètres non nuls.
Voici le 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
Des idées comment faire cela?
La solution
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))
Autres conseils
Nous avons utilisé beaucoup de COALESCE
dans le passé pour " clauses WHERE dynamiques " comme vous parlez.
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 '\')
Un gros problème se pose toutefois lorsque vous souhaitez éventuellement filtrer une colonne qui est également nullable ... si les données de la colonne sont null
pour une ligne donnée ET si l'utilisateur n'a pas entré Tout élément à rechercher dans cette colonne (la saisie de l'utilisateur est donc également null
), cette ligne n'apparaîtra même pas dans les résultats (ce qui, si vos filtres sont facultatif, est un comportement d'exclusion incorrect).
Afin de compenser les champs nullables, vous devez faire en sorte que le code SQL soit plus compliqué:
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))
Pour votre compréhension, IF est un code de procédure en T-SQl. Il ne peut pas être utilisé dans une instruction insert / update / delete / select. Il peut uniquement être utilisé pour déterminer laquelle des deux instructions vous souhaitez exécuter. Lorsque vous avez besoin de différentes possibilités dans une instruction, vous pouvez procéder comme ci-dessus ou utiliser une instruction CASE.
Vous pouvez également utiliser la fonction IsNull ou 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)
Cela fait la même chose que la suggestion de Michael ci-dessus ...
IsNull () et Coalesce () fonctionnent plus ou moins de la même manière, ils renvoient le premier argument non-Null de la liste, sauf que iSNull n'autorise que 2 arguments et que Coalesce peut prendre n'importe quel nombre ...
http: / /blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx
Essayez de placer votre instruction IF autour de la totalité de l’instruction SQL. Cela signifie qu’il y aura une instruction SQL pour chaque condition. Cela a fonctionné pour moi.