Un metodo potrebbe essere quello di utilizzare una variante di
WHERE column = nvl(var, column)
Ci sono tuttavia due insidie qui:
-
se la colonna è nullable, questa clausola filtrerà i valori null mentre nella tua domanda non filtreresti i valori null nel secondo caso. Potresti modificare questa clausola per prendere in considerazione i null ma diventa brutta:
WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
Ovviamente se in qualche modo il
impossible_value
viene inserito, ti imbatterai in altri tipi di problemi (divertenti). - L'ottimizzatore non comprende correttamente questo tipo di clausola. A volte produrrà un piano con UNION ALL ma se ci sono più di un paio di
nvl
, otterrai una scansione completa anche se sono presenti indici perfettamente validi.
Questo è il motivo per cui quando ci sono molti parametri (diversi campi di ricerca in una grande forma per esempio), mi piace usare l'SQL dinamico:
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;
Puoi anche usare EXECUTE IMMEDIATE l_query INTO l_result USING param1;