1
votes

Ma sous-requête a renvoyé plus d'une valeur dans l'instruction CASE

J'ai essayé de récupérer des données de ma procédure stockée. @ContactID est le paramètre d'entrée, où l'utilisateur clique sur le bouton d'affichage de la requête. Donc, si @ContactID est nul, alors je veux retourner la table entière et quand @ContactID a une valeur, alors je veux retourner seulement cette ligne spécifique. Merci

DECLARE @ContactID INT = NULL

SELECT * 
FROM Contact C 
WHERE C.PK_Contact IN (CASE WHEN @ContactID IS NULL THEN (SELECT PK_Contact FROM Contact) ELSE @ContactID END)

Mais j'obtiens cette erreur:

La sous-requête a renvoyé plus d'une valeur. Cela n'est pas autorisé lorsque la sous-requête suit =,! =, ,> = Ou lorsque la sous-requête est utilisée comme expression.


4 commentaires

select PK_Contact from Contact renvoie tous les PK_Contact s de la table Contact .


Quel est le type de données du paramètre @ContactID et ce qu'il contient? Utilisez-vous SQL Server 2008 ou 20012? BTW SQL Server 2008 n'est plus pris en charge, vous devriez vraiment mettre à niveau


oui donc je veux que WHERE C.PK_Contact IN (renvoyé tous les PK de la table Contact)


@Sami Désolé pour la balise sql-2008 et 12. Je viens de rejoindre le débordement de pile donc je ne sais pas comment poster.


3 Réponses :


0
votes

Supprimez IN et la sous-requête:

WHERE C.PK_Contact = C.PK_Contact 

Ainsi, lorsque @ContactID est NULL la condition est

declare @ContactID int =null
SELECT * 
FROM Contact C 
WHERE C.PK_Contact = (CASE WHEN @ContactID IS NULL THEN C.PK_Contact ELSE @ContactID END)

qui est toujours TRUE et cela renverra toutes les lignes.


0 commentaires

4
votes

Pouvez-vous simplement essayer ceci à la place?

-- you should *really* get in the habit of explicitly spelling out which columns you need! 
-- Don't use "SELECT *" in production code!
SELECT *    
FROM dbo.Contact C 
WHERE C.PK_Contact = ISNULL(@ContactID, C.PK_Contact)

Si @ContactID a une valeur spécifique, vous ne renvoyez que les lignes qui correspondent à Valeur de l'ID . Si @ContactID est NULL, vous renvoyez toutes les lignes.


7 commentaires

@Hrv Vous devez marquer la meilleure réponse pour résoudre votre problème comme accepté. Veuillez choisir l'une des deux réponses.


@Sami oui bien sûr. mais cela donnera popup que je peux accepter la réponse après 3 minutes!


@Hrv. . . C'est la meilleure solution. Il n'utilise que des opérations booléennes de base, plutôt que d'introduire des expressions case dans la clause where .


@GordonLinoff et où est le problème avec l'expression de cas qui est un standard? Comment est-ce mieux? Il n'utilise que des opérations booléennes de base Une instruction case utilise-t-elle quelque chose de différent moins efficace?


@forpas. . . Les expressions case imposent un ordre lors de l'évaluation. C'est la seule expression qui a vraiment une telle contrainte d'ordre. Cela tue à peu près l'optimiseur.


@Hrv prend un certain temps et lisez pourquoi devrait éviter d'utiliser des fonctions comme ISNULL () dans la clause WHERE: blog.sqlauthority.com/2013/03/12/... et mssqltips.com/sqlservertip/1236/... et mssqltips.com/sqlservertutorial/3204/… < / a>


@GordonLinoff Je vois que mon commentaire précédent est supprimé et je ne sais pas pourquoi! Depuis quand les commentaires techniques sont-ils supprimés? Encore une fois: pensez-vous que l'optimiseur est plus heureux avec une fonction qu'avec une instruction CASE? Si oui, en avez-vous la preuve? J'ai posté des liens dans mon commentaire précédent pour prouver pourquoi les fonctions devraient être évitées. En avez-vous pour soutenir ce que vous avez dit?