Was passiert eigentlich, wenn du eine SQL Abfrage ausführst, welche dir keine Zeilen zurück liefert? Denke Beispielsweise an eine WHERE Clausel mit der Bedingung 1=2, welche nie erfüllt sein kann und somit auch nie Zeilen retourniert werden können.
Als erstes sollten wir uns ein paar Beispiele anschauen, welche dir verdeutlichen sollen, was du als Rückgabewert für verschieden Szenarien erwarten kannst.
SELECT *
FROM DUAL
WHERE 1=1
-- Return: X
SELECT *
FROM DUAL
WHERE 1=2
-- Return: - (nicht NULL!)
SELECT NVL(DUMMY,1)
FROM DUAL
WHERE 1=2
-- Return: - (nicht NULL!)
SELECT COUNT(*)
FROM DUAL
WHERE 1=2
-- Return: 0
SELECT MAX(dummy)
FROM DUAL
WHERE 1=2
-- Return: NULL
NVL und NVL2
Wie du am oberen Beispiel gesehen hast, kannst du NVL und NVL2 nicht verwenden, da keine Zeilen zurück geliefert werden. Die Verwendung von NVL als auch NVL2 macht nur dann Sinn, wenn Zeilen zurück geliefert werden, wobei nicht jeder Spaltenwert einen Inhalt besitzt. Dieser kann dann mithilfe dieser Funktionen abgeändert oder verändert werden. Für unser Problem scheidet aber hier NVL und NLV2 getrost aus. Nähere Informationen über die richtige Verwendung sowie vielen Tricks und Tipps gibt es im Artikel über NVL und NVL2.
MAX/MIN in Verbindung mit NVL oder COALESCE
Ein Trick um eine Zeile retourniert zu bekommen ist die Verwendung der Funktion MAX oder MIN in Verbindung mit MAX oder MIN. Die Funktionen MAX oder MIN liefern immer einen Zeilenwert zurück, sofern dieser auch NULL ist. Mit MAX oder MIN wird also zumindest immer eine Zeile retourniert. Nun kannst du mit den Funktionen NVL, NVL2 oder COALESCE diesen Wert verändern. Dies ist ein schneller Vorgang um auch auf Abfragen zu reagieren, welche keine Zeilen als Rückgabewert liefern würden.
Unten findest du zwei Beispiele, welche dir verdeutlichen sollen, wie das Konzept funktioniert. Wie du siehst, wird nun zumindest ein Wert zurückgegeben.
SELECT NVL(MAX(dummy), 'Z')
FROM DUAL
WHERE 1=2
-- Return: Z
SELECT COALESCE(MAX(dummy), 'Z')
FROM DUAL
WHERE 1=2
-- Return: Z
CASE und EXISTS
Eine weitere Möglichkeit ist die Abfrage mit einer WENN Klausel. Dafür nimmst du dir die Funktion EXISTS zur Hilfe und prüfst, ob es überhaupt eine Zeile gibt, welche zurückkommen würde. Dafür prüfst du im ersten Schritt, ob eine Zeile in deiner Abfrage existiert. Ist dies der Fall, so kannst du die Zeilen ausgeben. Sollte jedoch keine Zeile existieren, so kannst du über den ELSE Zweig eine Alternative ausgeben und bekommst somit ebenso immer eine Zeile angezeigt.
SELECT CASE
WHEN EXISTS
(SELECT 1
FROM DUAL
WHERE 1=2)
THEN
(SELECT *
FROM DUAL
WHERE 1=2)
ELSE 'Z'
END
FROM DUAL
-- Return: Z
CASE und COUNT
Eine andere Möglichkeit ist das CASE Statement in Verbindung mit der Funktion COUNT. Wie du oben bereits gesehen hast, liefert dir COUNT die Anzahl der zurückgegebenen Zeilen und kann dir somit sogar die Zahl 0 (sofern keine Zeile zurück gegeben wird) liefern. Sollte COUNT eine positive Zahl sein, so werden die Werte der Abfrage ausgegeben. Bei der Anzahl 0 soll hingegen der alternative Pfad ausgewählt werden, wodurch jedenfalls eine Zeile als Rückgabewert geliefert wird.
SELECT CASE
WHEN
(SELECT COUNT(*)
FROM DUAL
WHERE 1=2) <> 0
THEN
(SELECT *
FROM DUAL
WHERE 1=2)
ELSE 'Z'
END
FROM DUAL
-- Return: Z
Weitere Tipps und Tricks zum SQL Developer sowie zu SQL und Datenbanken findest du auf der Übersichtsseite.