Een methode zou zijn om een variant van
. te gebruiken WHERE column = nvl(var, column)
Er zijn hier echter twee valkuilen:
-
als de kolom nullbaar is, filtert deze clausule null-waarden, terwijl u in uw vraag de null-waarden in het tweede geval niet zou filteren. Je zou deze clausule kunnen aanpassen om rekening te houden met nulls, maar het wordt lelijk:
WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
Natuurlijk als op de een of andere manier de
impossible_value
ooit is ingevoegd, zul je andere (leuke) problemen tegenkomen. - De optimizer begrijpt dit type clausule niet goed. Het zal soms een plan opleveren met een UNION ALL, maar als er meer dan een paar
nvl
zijn , krijgt u een volledige scan, zelfs als er perfect geldige indexen aanwezig zijn.
Dit is de reden waarom ik, wanneer er veel parameters zijn (meerdere zoekvelden in een grote vorm bijvoorbeeld), ik graag dynamische SQL gebruik:
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;
U kunt ook EXECUTE IMMEDIATE l_query INTO l_result USING param1;
gebruiken