2009-09-21 13 views
37

Używam procedury przechowywanej w MySQL, z instrukcją CASE.Jak wybrać pusty zestaw wyników?

W klauzuli ELSE CASE (odpowiednik domyślnie:) Chcę wybrać i zwrócić pusty zestaw wyników, unikając w ten sposób zgłaszania błędu SQL, nie obsługując przypadku ELSE, i zamiast tego zwracać pusty zestaw wyników jako jeśli zwykłe zapytanie nie zwróciło żadnych wierszy.

Do tej pory udało mi się to zrobić za pomocą czegoś takiego:
Select NULL From users Where False

Ale muszę wymienić istniejącą tabelę, jak „użytkowników” w tym przykładzie. To działa, ale wolałbym bardziej elegancki sposób, który nie psuje się, jeśli nazwa lub nazwa tabeli zostanie zmieniona lub usunięta.

Próbowałem już Select NULL Where False, ale to nie działa.

Użycie Select NULL nie zwraca pustego zestawu, ale jeden wiersz z kolumną o wartości NULL i wartością NULL.

+0

Byłby to dziwny schemat, gdyby nie jeden stół, który można zagwarantować! – onedaywhen

+0

Masz rację. Istnieje wiele tabel, które istnieją, problem polega na tym, że po wybraniu jednej tabeli, jeśli w przyszłości ta tabela zostanie upuszczona lub zmieniona, napisany kod przestanie działać, a ty będziesz łączył dwie części oprogramowania, które nie mają nic ze sobą zrobić, ale jedna zmiana w jednym z nich powoduje, że drugi przestaje działać.To się nazywa sprzężenie, a sprzężenie w oprogramowaniu jest generalnie złym pomysłem. – Petruza

+1

@Petruza: W czasach, w których korzystałem z Access/Jet, mój schemat zawierałby stałą tabelę pomocniczą o nazwie "RowRowTable". – onedaywhen

Odpowiedz

37

W MySQL znajduje się tablica typu "dual", z której powinieneś być w stanie skorzystać.

select 
    1 
from 
    dual 
where 
    false 

To zawsze da ci pusty wynik.

+0

Tak. 'dual' rodzi się w tym celu. – Rockallite

+0

Niestety, to rozwiązanie nie działa w podkwerendach IN w MySQL pod 5.7. 'wybierz 1 w (SELECT 1 FROM dual WHERE FALSE);' zwraca 1. Tylko rozwiązanie zaproponowane przez @dhruvbird działało dla mnie – ENargit

2

Co powiesz na to?

SELECT 'MyName' AS EmptyColumn 
FROM dual 
WHERE 'Me' = 'Funny' 
+0

Próbowałem czegoś takiego, ale domyślam się, że użycie Where without From nie jest legalne przynajmniej w MySQL, dunno ANSI SQL. – Petruza

+0

Powoduje to błąd składni w MySQL 5.5. – Rockallite

8

Jak o

SELECT * FROM (SELECT 1) AS TBL WHERE 2=3 

sprawdzone w myphp, a także działa w SQLite i prawdopodobnie w żadnym innym db silnika.

+0

Dobrze. Działa to w podzapytaniach w MySQL 5.5. – Rockallite

3

To prawdopodobnie będzie działać we wszystkich bazach danych.

SELECT * FROM (SELECT NULL AS col0) AS inner0 WHERE col0 IS NOT NULL; 
1
SELECT * FROM (SELECT NULL) WHERE 0 
+3

Świadcząc kod, który rozwiązuje ten problem, najlepiej jest też dać przynajmniej krótkie wyjaśnienie jak to działa tak, że ludzie nie będą musieli czytać psychicznie przetworzy go linia po linii, aby zrozumieć różnice. – Fluffeh

+5

na mojej wersji mysql musiałem dodać alias: SELECT * FROM (SELECT NULL) WHERE 0; – shark555

15

powinno działać w większości DB, testowano na Postgres'a i Netezza:

SELECT NULL LIMIT 0; 
+4

Najbardziej lubię to rozwiązanie. Działa również w MySQL (w wersji 5.5). – noodl

+1

Nie, to nie działa w podzapytaniu w MySQL. Podnieść błąd 'Ta wersja MySQL nie obsługuje jeszcze„LIMIT & IN/ALL/ANY/SOME subquery'' (v5.5). Tak więc ta odpowiedź nie jest odpowiednia dla tego pytania. – Rockallite

+1

LIMIT nie jest standardem, więc oczywiście nie może działać na "dowolnym DB". Spróbuj na przykład MSSQL lub DB2. –

3
SELECT TOP 0 * FROM [dbo].[TableName] 

To rozsądne podejście do stałego operatora skanowania.

+0

PO poprosił o zapytania bez konieczności podać nazwę istniejącej tabeli, która wymaga odpowiedź. – Marki555

0

W PostgreSQL proste

SELECT; 

prace. Nie otrzymasz nawet kolumn oznaczonych jako "nieznane".
Pamiętaj jednak, że nadal jest wyświetlany wiersz o numerze: .

+0

Technicznie nie jest to pusty zestaw wyników, prawda? Co powiesz na 'wybierz gdzie fałsz'? –

+0

Zamiast 0 wierszy, to zwraca 0 kolumn. – luckydonald