dynamische WHERE Klausel

16/05/2008 - 14:02 von Rene Kadner | Report spam
Hallo,

Ich möchte eine Abfrage mit dynamischen Auswahlkriterien ausführen. Bisher
habe ich das immer im Code der Applikation zusammengebaut (mit if then else
Blöcken). Das möchte ich gern in eine Prozedur auslagern. Dort könnte ich
mir einen String zusammenbauen und den per exec ausführen. Das ist aber
nicht lesbar, die Codevervollstàndigung klappt nicht (SQL Prompt), und
farblich ist auch nichts mehr zu machen - alles grün.

DECLARE @ma_id INT
SET @ma_id = 0

SELECT * FROM ...

WHERE (CASE @ma_id WHEN 0 THEN [bearbeiter_id] > 0 ELSE [bearbeiter_id] =
@ma_id)

dieser Ansatz wàre toll, aber das geht leider nicht. Gibt es evtl. doch
etwas alternatives?


Gruß
René
 

Lesen sie die antworten

#1 Christoph Ingenhaag
16/05/2008 - 14:43 | Warnen spam
"Rene Kadner" wrote:

Hallo,

Ich möchte eine Abfrage mit dynamischen Auswahlkriterien ausführen. Bisher
habe ich das immer im Code der Applikation zusammengebaut (mit if then else
Blöcken). Das möchte ich gern in eine Prozedur auslagern. Dort könnte ich
mir einen String zusammenbauen und den per exec ausführen. Das ist aber
nicht lesbar, die Codevervollstàndigung klappt nicht (SQL Prompt), und
farblich ist auch nichts mehr zu machen - alles grün.

DECLARE @ma_id INT
SET @ma_id = 0

SELECT * FROM ...

WHERE (CASE @ma_id WHEN 0 THEN [bearbeiter_id] > 0 ELSE [bearbeiter_id] =
@ma_id)

dieser Ansatz wàre toll, aber das geht leider nicht. Gibt es evtl. doch
etwas alternatives?


Gruß
René




Hi Rene,

gehen tut so etwas in der Art, wenn mann es anders schreibt:
(Ich geh hier davon aus, wenn @ma_id = 0 sollen alle ausgegeben werden)
...
where
bearbeiter_id between @ma_id and
case
when @ma_id = 0 then 2147483647
else @ma_id
end

Das so zu machen ist aber alles andere als eine gute Idee: Bei SQL kommt es
nicht darauf an, den Code möglichst trickreich zu schreiben, sondern die
Ausführung der Abfrage zu optimieren. Hiermit würdest du das Gegenteil
bewirken. Ich gehe davon aus, das bearbeiter_id ein Primary oder Foreign Key
ist. Erstere ist automatisch indiziert, zweiterer sollte indiziert werden.
Bei der obigen where clause würde immer ein Index Scan, durchgeführt werden
(das ist hier sogar Glück im Unglück, Stichwort Parameter Sniffing) statt
eines Index Seeks.
Besser 2 Statements mit IF Abfrage. Dann gibts bei der 0 einen Scan und bei
<> 0 einen Seek. Damit brauchst du es dann auch nicht mehr mit dynamischen
SQL zu machen. Ich würde eine Prozedur für die IF Verzweigungen machen, die
die Prozeduren für die eigentliche Abfrage aufruft, oder den Client
verschiedene Prozeduren aufrufen lassen.

Über dynamisches SQL an sich gibts einen Atikel bei http://www.insidesql.org/


Vg
Christoph

Ähnliche fragen