sql >> Databáze >  >> RDS >> Sqlserver

Oprava Msg 512 „Poddotaz vrátil více než 1 hodnotu“ v SQL Server

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.


  1. PostgreSQL:Jak nastavím search_path na uživatelské úrovni?

  2. Najděte v PostgreSQL hodnoty, které neobsahují čísla

  3. PostgreSQL - maximální počet parametrů v klauzuli IN?

  4. Dotazování dat spojením dvou tabulek ve dvou databázích na různých serverech