Един от методите би бил да използвате вариант на
WHERE column = nvl(var, column)
Тук обаче има два капана:
-
ако колоната е nullable, тази клауза ще филтрира null стойности, докато във вашия въпрос не бихте филтрирали null стойностите във втория случай. Можете да модифицирате тази клауза, за да вземе предвид нули, но става грозно:
WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
Разбира се, ако по някакъв начин
impossible_value
бъде вмъкнат, ще се натъкнете на друг вид (забавни) проблеми. - Оптимизаторът не разбира правилно този тип клауза. Понякога ще създаде план с UNION ALL, но ако има повече от няколко
nvl
, ще получите пълно сканиране, дори ако са налице напълно валидни индекси.
Ето защо, когато има много параметри (няколко полета за търсене в голяма форма например), обичам да използвам динамичен SQL:
DECLARE
l_query VARCHAR2(32767) := 'SELECT ... JOIN ... WHERE 1 = 1';
BEGIN
IF param1 IS NOT NULL THEN
l_query := l_query || ' AND column1 = :p1';
ELSE
l_query := l_query || ' AND :p1 IS NULL';
END IF;
/* repeat for each parameter */
...
/* open the cursor dynamically */
OPEN your_ref_cursor FOR l_query USING param1 /*,param2...*/;
END;
Можете също да използвате EXECUTE IMMEDIATE l_query INTO l_result USING param1;