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_valuenå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;