Se ricevi un messaggio di errore 512 che dice "La sottoquery ha restituito più di 1 valore..." in SQL Server, è perché stai usando una sottoquery che restituisce più di un valore in uno scenario in cui ciò non è consentito.
Esempio di errore
Supponiamo di avere le seguenti due tabelle:
SELECT * FROM Dogs;
SELECT * FROM Cats;
Risultato:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 4 | Fluffy | +---------+-----------+ +---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Ed eseguiamo la seguente query su queste due tabelle:
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats );
Risultato:
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.
Possiamo vedere che ha provocato l'errore Msg 512.
Questo messaggio di errore ci dice esplicitamente che "La sottoquery ha restituito più di 1 valore" e che "Ciò non è consentito quando la sottoquery segue =, !=, <, <=,>,>=o quando la sottoquery viene utilizzata come espressione ”.
La soluzione a questo dipenderà da cosa stai cercando di fare nella query. Di seguito sono riportate un paio di opzioni per risolvere questo problema.
Soluzione 1
Un modo per affrontare questo problema è utilizzare un operatore diverso. Quello che voglio dire è, usa un operatore diverso da =
, !=
, <
, <=
, >
o >=
.
Ecco un esempio che utilizza IN
operatore:
SELECT * FROM Dogs
WHERE DogName IN ( SELECT CatName FROM Cats );
Risultato:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Soluzione 2
Un'altra opzione è mantenere l'uguale (=
) (o qualsiasi operatore sia nella query originale), ma cambia la sottoquery.
Ecco un esempio di modifica della sottoquery, mantenendo l'operatore uguale:
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats WHERE CatId = 2 );
Risultato:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
In questo caso la sottoquery ha restituito un solo valore e l'operatore equals andava bene con quello.
Soluzione 3
Si noti che le sottoquery precedenti restituiscono solo una colonna. Se le sottoquery restituiscono più colonne, dovremmo modificare la query esterna in modo che utilizzi EXISTS
operatore.
Esempio:
SELECT * FROM Dogs d
WHERE EXISTS ( SELECT * FROM Cats c WHERE c.CatName = d.DogName );
Risultato:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Se non lo abbiamo modificato per utilizzare EXISTS
operatore, probabilmente riceveremmo il messaggio di errore 116.