Um método seria usar uma variante de
WHERE column = nvl(var, column)
Existem duas armadilhas aqui, no entanto:
-
se a coluna for anulável, esta cláusula filtrará valores nulos, enquanto na sua pergunta você não filtraria os valores nulos no segundo caso. Você pode modificar esta cláusula para levar em consideração nulos, mas fica feio:
WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
Claro que se de alguma forma oimpossible_value
for inserido, você terá algum outro tipo de problema (divertido).
- O otimizador não entende corretamente esse tipo de cláusula. Às vezes, ele produzirá um plano com um UNION ALL, mas se houver mais do que alguns
nvl
, você obterá uma verificação completa mesmo se houver índices perfeitamente válidos.
É por isso que quando há muitos parâmetros (vários campos de pesquisa em um formulário grande, por exemplo), gosto de usar SQL dinâmico:
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;
Você também pode usar
EXECUTE IMMEDIATE l_query INTO l_result USING param1;