Pokud se na serveru SQL zobrazí chybová zpráva 512, která čte „Poddotaz vrátil více než 1 hodnotu…“, je to proto, že používáte poddotaz, který vrací více než jednu hodnotu ve scénáři, kde to není povoleno.
Příklad chyby
Předpokládejme, že máme následující dvě tabulky:
SELECT * FROM Dogs;
SELECT * FROM Cats;
Výsledek:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 4 | Fluffy | +---------+-----------+ +---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
A proti těmto dvěma tabulkám spustíme následující dotaz:
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats );
Výsledek:
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.
Vidíme, že to vedlo k chybě Msg 512.
Tato chybová zpráva nám výslovně říká, že „Poddotaz vrátil více než 1 hodnotu“ a že „Toto není povoleno, když poddotaz následuje =, !=, <, <=,>,>=nebo když je poddotaz použit jako výraz “.
Řešení bude záviset na tom, co se v dotazu pokoušíte udělat. Níže je uvedeno několik možností, jak tento problém vyřešit.
Řešení 1
Jedním ze způsobů, jak se s tím vypořádat, je použití jiného operátora. Mám na mysli použití jiného operátoru než =
, !=
, <
, <=
, >
, nebo >=
.
Zde je příklad, který používá IN
operátor:
SELECT * FROM Dogs
WHERE DogName IN ( SELECT CatName FROM Cats );
Výsledek:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Řešení 2
Další možností je ponechat se rovná (=
) (nebo kterýkoli operátor v původním dotazu), ale změňte poddotaz.
Zde je příklad změny dílčího dotazu při zachování operátoru rovná se:
SELECT * FROM Dogs
WHERE DogName = ( SELECT CatName FROM Cats WHERE CatId = 2 );
Výsledek:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
V tomto případě poddotaz vrátil pouze jednu hodnotu a operátor rovná se s tím byl v pořádku.
Řešení 3
Všimněte si, že výše uvedené poddotazy vracejí pouze jeden sloupec. Pokud poddotazy vracely více sloupců, museli bychom změnit vnější dotaz tak, aby používal EXISTS
operátor.
Příklad:
SELECT * FROM Dogs d
WHERE EXISTS ( SELECT * FROM Cats c WHERE c.CatName = d.DogName );
Výsledek:
+---------+-----------+ | DogId | DogName | |---------+-----------| | 2 | Fluffy | | 4 | Fluffy | +---------+-----------+
Pokud jsme jej nezměnili tak, aby používal EXISTS
operátora, pak bychom pravděpodobně dostali chybovou zprávu 116.