Si vous obtenez l'erreur Msg 512 indiquant "La sous-requête a renvoyé plus d'une valeur…" dans SQL Server, c'est parce que vous utilisez une sous-requête qui renvoie plusieurs valeurs dans un scénario où cela n'est pas autorisé.
Exemple d'erreur
Supposons que nous ayons les deux tables suivantes :
SELECT * FROM Dogs;
SELECT * FROM Cats;
Résultat :
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 4 | Fluffy | +---------+-----------+ +---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Et nous exécutons la requête suivante sur ces deux tables :
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats );
Résultat :
Msg 512, Level 16, State 1, Line 1 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Nous pouvons voir que cela a entraîné l'erreur Msg 512.
Ce message d'erreur nous indique explicitement que la "sous-requête a renvoyé plus d'une valeur" et que "ceci n'est pas autorisé lorsque la sous-requête suit =, !=, <, <=,>,>=ou lorsque la sous-requête est utilisée comme expression ”.
La solution dépendra de ce que vous essayez de faire dans la requête. Vous trouverez ci-dessous quelques options pour résoudre ce problème.
Solution 1
Une façon de résoudre ce problème consiste à utiliser un opérateur différent. Ce que je veux dire, c'est utiliser un opérateur autre que =
, !=
, <
, <=
, >
, ou >=
.
Voici un exemple qui utilise le IN
opérateur :
SELECT * FROM Dogs
WHERE DogName IN ( SELECT CatName FROM Cats );
Résultat :
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Solution 2
Une autre option est de garder les égaux (=
) (ou n'importe quel opérateur dans la requête d'origine), mais modifiez la sous-requête.
Voici un exemple de modification de la sous-requête, tout en conservant l'opérateur égal :
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats WHERE CatId = 2 );
Résultat :
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Dans ce cas, la sous-requête n'a renvoyé qu'une seule valeur, et l'opérateur égal convenait à cela.
Solution 3
Notez que les sous-requêtes ci-dessus ne renvoient qu'une seule colonne. Si les sous-requêtes renvoyaient plusieurs colonnes, nous devions modifier la requête externe afin qu'elle utilise le EXISTS
opérateur.
Exemple :
SELECT * FROM Dogs d
WHERE EXISTS ( SELECT * FROM Cats c WHERE c.CatName = d.DogName );
Résultat :
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Si nous ne l'avons pas changé pour utiliser le EXISTS
opérateur, nous aurions probablement le message d'erreur 116.