Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Behebung von Msg 512 „Unterabfrage hat mehr als 1 Wert zurückgegeben“ in SQL Server

Wenn Sie in SQL Server die Fehlermeldung 512 mit der Aufschrift „Unterabfrage hat mehr als einen Wert zurückgegeben…“ erhalten, liegt dies daran, dass Sie eine Unterabfrage verwenden, die mehr als einen Wert in einem Szenario zurückgibt, in dem dies nicht zulässig ist.

Fehlerbeispiel

Angenommen, wir haben die folgenden zwei Tabellen:

SELECT * FROM Dogs;

SELECT * FROM Cats;

Ergebnis:

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
| 4       | Fluffy    |
+---------+-----------+

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Und wir führen die folgende Abfrage für diese beiden Tabellen aus:

SELECT * FROM Dogs 
WHERE DogName = ( SELECT CatName FROM Cats );

Ergebnis:

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.

Wir können sehen, dass dies zu Fehler Msg 512 geführt hat.

Diese Fehlermeldung teilt uns ausdrücklich mit, dass die „Unterabfrage mehr als 1 Wert zurückgegeben hat“ und dass „Dies nicht zulässig ist, wenn die Unterabfrage auf =, !=, <, <=,>,>=folgt oder wenn die Unterabfrage als Ausdruck verwendet wird “.

Die Lösung hierfür hängt davon ab, was Sie in der Abfrage tun möchten. Nachfolgend finden Sie einige Optionen zur Lösung dieses Problems.

Lösung 1

Eine Möglichkeit, damit umzugehen, besteht darin, einen anderen Operator zu verwenden. Was ich meine ist, verwenden Sie einen anderen Operator als = , != , < , <= , > , oder >= .

Hier ist ein Beispiel, das den IN verwendet Betreiber:

SELECT * FROM Dogs 
WHERE DogName IN ( SELECT CatName FROM Cats );

Ergebnis:

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 2       | Fluffy    |
| 4       | Fluffy    |
+---------+-----------+

Lösung 2

Eine andere Möglichkeit besteht darin, die Gleichheit beizubehalten (= )-Operator (oder welcher Operator auch immer in der ursprünglichen Abfrage enthalten ist), aber ändern Sie die Unterabfrage.

Hier ist ein Beispiel für das Ändern der Unterabfrage unter Beibehaltung des Gleichheitsoperators:

SELECT * FROM Dogs 
WHERE DogName = ( SELECT CatName FROM Cats WHERE CatId = 2 );

Ergebnis:

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 2       | Fluffy    |
| 4       | Fluffy    |
+---------+-----------+

In diesem Fall gab die Unterabfrage nur einen Wert zurück, und der Gleichheitsoperator war damit einverstanden.

Lösung 3

Beachten Sie, dass die obigen Unterabfragen nur eine Spalte zurückgeben. Wenn die Unterabfragen mehrere Spalten zurückgeben, müssen wir die äußere Abfrage so ändern, dass sie den EXISTS verwendet Betreiber.

Beispiel:

SELECT * FROM Dogs d
WHERE EXISTS ( SELECT * FROM Cats c WHERE c.CatName = d.DogName );

Ergebnis:

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 2       | Fluffy    |
| 4       | Fluffy    |
+---------+-----------+

Wenn wir es nicht geändert haben, um den EXISTS zu verwenden Operator, dann würden wir wahrscheinlich die Fehlermeldung 116 erhalten.