Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Correction de Msg 512 "La sous-requête a renvoyé plus d'une valeur" dans SQL Server

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.