Was versteht man unter einer dynamischen Abfrage?
Wenn man mit Variablen arbeitet, kommt es öfters vor das wir die Variable in die WHERE-Bedingung einbauen und somit eine Überprüfung durchführen. Macht allerdings ohne Prozedur oder Funktion eher weniger Sinn. Deshalb übergeben wir der Prozedur eine Variable die z.B. eine ID enthält.
Create Procedure usp_test (@ID int)
as
Select * from tbl_test
where TID = @ID
Mit Hilfe der Prozedur wird nur nach dem Übergebenen Wert gesucht und der dementsprechende Datensatz/e ausgegeben.
So viel dazu…
Jetzt wäre es Interessant eine Prozedur zu schreiben, die in der Variable einen bestehenden Tabellenbezeichner übergeben bekommt. Der Gedanke ist eine Prozedur zu schreiben, der ich in Form eines Parameter den Tabellennamen übergebe und der SQL Server mir nun die dementsprechende Tabelle zurück gibt. Nun wird der ein oder andere denken: “Wo ist das Problem???”.
Zeit zum testen!
Logischer Gedanke:
Create Procedure usp_test (@table varchar(50))
as
Select * from @table
Bereits beim erstellen der Prozedur wird folgende Fehlermeldung ausgeworfen:
Meldung 1087, Ebene 16, Status 1, Prozedur usp_test, Zeile 3
Die @table-Tabellenvariable muss deklariert werden.
Die Lösung des ganzen, ist ein bisschen “gebastelte”.
Create Procedure usp_test (@table varchar(50))
as
exec('select * from ' + @table)
Es wird die “exec”-Anweisung gebraucht, diese ist normalerweise für den Aufruf von Prozeduren zuständig.
Schlichtweg machen wir nichts anderes als das fertige Select-Statement zusammen zu “basteln”.
Wichtig ist noch das hinter dem ersten Teil noch ein Blank sein muss (da sonst der Tabellenbezeichner und das From zusammen stehen, was zum Syntax-Fehler führt) und falls die Variable kein Zeichen-Datentyp sein sollte (warum auch immer), muss sie konvertiert werden.
Es gäbe noch eine zweite Variante das zu lösen und zwar mit der Stored Procedure: sp_executesql
Beispiel mit sp_executesql:
Create Procedure usp_test (@table varchar(50))
as
Declare @sqlstring nchar(100)
Set @sqlstring = N'Select * from ' + @table
exec sp_executesql @sqlstring
Die Variable hier, @sqlstring, muss vom Typ nchar(..) sein, sonst kommt es zu einer Fehlermeldung.
Der Aufruf der Prozedur ist nun kalter Kaffee:
…und das wars.
Problematik: Dynamische SQL-Abfragen sollten vermieden werden, da die damit verbundenen Risiken, etwa SQL Injection oder das Überfluten des Plancaches zu hoch sind. Allerdings kommen wir in manchen Fällen nicht ohne aus…