En metod skulle vara att använda en variant av
WHERE column = nvl(var, column)
Det finns dock två fallgropar här:
-
om kolumnen är nullbar kommer denna sats att filtrera nollvärden medan du i din fråga inte skulle filtrera nollvärdena i det andra fallet. Du kan ändra den här klausulen för att ta hänsyn till nollor, men den blir ful:
WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
Naturligtvis om på något sätt
impossible_value
någonsin infogas kommer du att stöta på någon annan typ av (roliga) problem. - Optimeraren förstår inte den här typen av klausul korrekt. Det kommer ibland att producera en plan med en UNION ALL men om det finns fler än ett par
nvl
, kommer du att få fullständig genomsökning även om helt giltiga index finns.
Det är därför jag gillar att använda dynamisk SQL, när det finns många parametrar (t.ex. flera sökfält i stor form:
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;
Du kan också använda EXECUTE IMMEDIATE l_query INTO l_result USING param1;