web-dev-qa-db-fra.com

Arguments facultatifs dans la clause WHERE

Supposons qu'il existe une procédure stockée ayant 3 paramètres. Parmi toutes les possibilités, je cherche à réaliser cela avec une seule clause WHERE sans perdre le contrôle en utilisant trop () AND () OR () ...

Exemple:

    //Params
@CITY VARCHAR(100) = NULL,
@GENDER VARCHAR(100) = NULL,
@AGE VARCHAR(100) = NULL

Je suppose que vous pouvez le faire en utilisant IF BEGIN ... END pour chaque variable si elle existe, mais cela rend le code beaucoup plus long que souhaité. 

Cette méthode ci-dessous ne fonctionnera pas, car elle est trop longue (il y a environ 10 champs différents comme celui-ci, mais l'exemple n'est que 3.) et je ne suis pas sûr que cela génère directement des valeurs distinctives ...

SELECT NAME FROM TABLE 
WHERE (
(CITY=@CITY AND GENDER=@GENDER AND AGE=@AGE)
OR (CITY=@CITY AND GENDER=@GENDER)
OR (GENDER=@GENDER AND AGE=@AGE)
OR (CITY=@CITY AND AGE=@AGE)
OR (CITY=@CITY)
OR (GENDER=@GENDER)
OR (AGE=@AGE)
)

Existe-t-il un moyen encore plus efficace et plus court encore?

Si oui, il est préférable que la méthode soit compatible avec JOIN également.

23
Control Freak

Alternativement aux options ISNULL/COALESCE, vous pouvez tester la nullité des paramètres:

SELECT NAME  
FROM TABLE  
WHERE  
    (@City IS NULL OR City = @City)
AND 
    (@Gender IS NULL OR Gender = @Gender)
AND 
    (@Age IS NULL OR Age = @Age) 
48
cjk

et ça?

SELECT
    NAME
FROM TABLE 
WHERE CITY = COALESCE(@CITY, CITY)
    AND GENDER = COALESCE(@GENDER, GENDER)
    AND AGE = COALESCE(@AGE, AGE)
11
silly

Essayez quelque chose comme ça:

SELECT NAME 
FROM TABLE 
WHERE 
    City = IsNull(@City, City) AND
    Gender = IsNull(@Gender, Gender) AND
    Age = IsNull(@Age, Age)

OU:

SELECT NAME 
FROM TABLE 
WHERE 
    (City = @City OR @City IS NULL) AND
    (Gender = @Gender OR @Gender IS NULL) AND
    (Age = @Age OR @Age IS NULL)
4
Greg
SELECT NAME   
FROM TABLE   
WHERE       
  City = case when isnull(@City ,'') = '' then City
                        else @City end
AND      
  Gender = case when isnull(@Gender ,'') = '' then Gender
                        else @Gender end
AND  
  Age = case when isnull(@Age ,0) = 0 then Age
                        else @Age end    
1
userGS

Peut-être ceci:

create procedure myProc
    --Params
@CITY VARCHAR(100) = NULL,
@GENDER VARCHAR(100) = NULL,
@AGE VARCHAR(100) = NULL
as

SELECT NAME FROM [TABLE]
WHERE ISNULL(CITY,'')=ISNULL(@CITY,ISNULL(CITY,''))
AND ISNULL(GENDER,'')=ISNULL(@GENDER,ISNULL(GENDER,''))
AND ISNULL(AGE,'')=ISNULL(@AGE,ISNULL(AGE,''))
go

En supposant que les colonnes de la clause WHERE sont nullables, utilisez ISNULL pour éviter la comparaison de null.

0
John Dewey