2009-08-14 6 views
2

Ich habe eine Auswahl wie die unten in einer gespeicherten Prozedur (verkürzt für die Kürze). @ Param ist ein Parameter für die gespeicherte Prozedur, die NULL sein kann.Will 'Exists' in einer Where-Klausel nur verwendet werden, wenn der übergebene Parameter einen Wert hat

SELECT name FROM Tabelle1 WHERE VORHANDEN (wählen .... von table2 Wo param = @param und ... und ...) und ... und ...

Ich möchte die EXISTS-Anweisung (der fett gedruckte Teil) wird nur verwendet, wenn @param einen Wert hat, andernfalls ignoriert es.

Ich möchte nicht dynamische SQL oder temporäre Tabellen verwenden, wenn möglich. Ich versuche, eine CASE-Anweisung zu verwenden, um mit der EXISTS-Anweisung zu arbeiten, aber mit wenig Glück.

+0

Um sicherzustellen, ... ist das Feld "param" akzeptieren NULLs ? –

+0

Ja .. Ich habe dies bereits in meiner Frage angegeben. –

Antwort

2
WHERE (@Param IS NULL OR EXISTS (SELECT ....)) 

Beachten Sie, dass dies keine Garantie ist - der Abfrageoptimierer wird tun, was er will. Aber ist sollte intelligent genug sein, um die bestehende Klausel zu optimieren.

+0

Das einzige, worauf Sie achten sollten, ist, dass die gespeicherte Prozedur den Ausführungsplan für den ersten ausgeführten Fall zwischenspeichert. Wahrscheinlich möchten Sie den Sproc als "WITH RECOMPILE" markieren - verlieren Sie den Vorteil des zwischengespeicherten Ausführungsplans, aber gewinnen Sie einen optimalen Plan für jeden Anruf. –

+0

Was fehlt mir hier? Wie wird die EXISTS-Anweisung nur verwendet, wenn @Param einen Wert hat, in diesem Beispiel? –

+0

Wenn Parameter einen Wert hat, ist der erste Teil dieses Ausdrucks falsch, und daher wird die exist-Klausel _will_ ausgeführt. Wenn param keinen Wert hat, wird der Ausdruck immer als wahr zurückgegeben, so dass EXISTS nicht aufgerufen werden muss. Die einzige Frage ist, ob der Abfrageoptimierer intelligent genug ist, dies zu realisieren. –

7

Die Verwendung der OR in der WHERE-Klausel wird höchstwahrscheinlich schrecklich langsam, besonders wenn EXISTS.

Weitere Optionen ...

Union: nur eine zurückkehren Reihen

SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = @param AND ... AND ...) AND ... AND ... 
UNION ALL 
SELECT name FROM Table1 WHERE @param IS NULL AND ... AND ... 

Bedingte Verzweigung:

IF @param2 IS NULL 
    SELECT name FROM Table1 WHERE ... AND ... 
ELSE 
    SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = @param AND ... AND ...) AND ... AND ... 
Verwandte Themen