J'ai rassemblé l'exemple ci-dessous pour expliquer ce que j'essaie de faire.
J'essaie de faire partie de la requête lorsque @FeatureID est NULL, puis renvoie tous les enregistrements dans la table # Temp pour ce ClientID . Si un @FeatureID contient un 1 par exemple, renvoyer l'enregistrement 1 et l'enregistrement NULL.
Où me suis-je trompé dans ma clause where?
CREATE TABLE #Temp
(
ClientID int,
FeatureID int
)
Insert into #Temp
(
ClientID,
FeatureID
)
SELECT
1,
1
UNION
SELECT
1,
2
UNION
SELECT
1,
3
UNION
SELECT
1,
NULL
Declare @ClientID int = 1
Declare @FeatureID int = NULL
--should return all 4 records
select * from #Temp
where ClientID = 1 and
FeatureID = IIF(@FeatureID IS NULL, FeatureID, @FeatureID)
Set @ClientID = 1
Set @FeatureID = 1
--should return the 1,1 record and the 1,NULL record
select * from #Temp
where ClientID = 1 and
FeatureID = IIF(@FeatureID IS NULL, FeatureID, @FeatureID)
drop table #Temp
3 Réponses :
Vous essayez effectivement de comparer NULL = NULL dans votre clause where qui ne fonctionne pas. NULL ne se compare pas à un autre NULL.
Pour votre première requête, ce que vous devez faire est de comparer uniquement la colonne d'ID de fonctionnalité lorsque @FeatureID n'est pas nul. Cela peut être accompli en testant la variable et en utilisant une condition OR.
select * from #Temp
where ClientID = 1 and
(
@FeatureID IS NULL
OR (@FeatureID IS NOT NULL AND (FeatureID IS NULL OR FeatureID=@FeatureID))
)
Dans la deuxième requête, vous devez comparer la colonne d'ID de fonctionnalité à la fois à @FeatureID et à NULL pour obtenir les deux lignes.
--should return the 1,1 record and the 1,NULL record select * from #Temp where ClientID = 1 and (@FeatureID IS NOT NULL AND (FeatureID IS NULL OR FeatureID=@FeatureID))
Pour gérer les deux cas dans une seule requête, utilisez deux conditions jointes par OR qui sont branchées selon que la variable est nulle ou non.
--should return all 4 records select * from #Temp where ClientID = 1 and (@FeatureID IS NULL OR FeatureID = @FeatureID)
Merci @kicken, je dois les combiner en une seule requête, ce n'était qu'un exemple. Est-ce possible?
Une formulation alternative qui pourrait être un peu plus simple:
select * from #Temp where ClientID = 1 and (ISNULL(@FeatureID, FeatureID) = FeatureID or FeatureID is NULL)
Si @FeatureID est nul, alors FeatureID = FeatureID , qui est toujours vrai. Sinon, il recherchera @FeatureID = FeatureID .
Il retournera toujours les lignes où FeatureID est nul.
Si vous souhaitez les combiner, cela devrait fonctionner:
select * from #Temp
where ClientID = 1 and
(@FeatureID is null
or
(@FeatureID is not null
and (FeatureID is null or FeatureID=@FeatureID)))
Cela sélectionnera tous les enregistrements lorsque @FeatureID = null et renverra 2 résultats {(1, null), (1, 1)} quand @FeatureID = 1