2013-12-19 3 views
16

Ich möchte Tabellenname in einer dynamischen SQL-Abfrage festlegen. Ich habe versucht, erfolgreich für die Parameter wie folgt:Wie legt man den Tabellennamen in der dynamischen SQL-Abfrage fest?

/* Using sp_executesql */ 
/* Build and Execute a Transact-SQL String with a single parameter 
value Using sp_executesql Command */ 

/* Variable Declaration */ 
DECLARE @EmpID AS SMALLINT 
DECLARE @SQLQuery AS NVARCHAR(500) 
DECLARE @ParameterDefinition AS NVARCHAR(100) 
/* set the parameter value */ 
SET @EmpID = 1001 
/* Build Transact-SQL String by including the parameter */ 
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = @EmpID' 
/* Specify Parameter Format */ 
SET @ParameterDefinition = '@EmpID SMALLINT' 
/* Execute Transact-SQL String */ 
EXECUTE sp_executesql @SQLQuery, @ParameterDefinition, @EmpID 

Jetzt mag ich TABLE NAME dynamisch über einen Parameter nehmen, aber ich habe nicht nachgewiesen, dass zu tun. Bitte führen Sie mich.

+0

Sie können den Tabellennamen nicht parametrisieren. Sie tun es einfach * manuell * im Schritt 'SET @ SQLQuery'. – MatBailie

+1

@MatBailie tatsächlich können Sie den Tabellennamen als String verwenden und Exec des String-Namen verwenden (es verhält sich genau wie eine Prozedur) – HellBaby

+1

@hellbaby - Und immer noch können Sie den Tabellennamen nicht als * Parameter * zu liefern 'sp_executesql', kann dies nur durch eine Substitution in die Zeichenkette erreicht werden. Diese sind sehr unterschiedlich. Die Parametrisierung ermöglicht Typprüfung, Schutz vor SQL-Injection-Attacken, Wiederverwendung von Ausführungsplänen usw. Das Ersetzen von Strings durch andere Strings tut dies nicht und das ist auch eine * nicht * -Parametrisierung. – MatBailie

Antwort

22

Tabellennamen können nicht als Parameter geliefert werden, so dass Sie die SQL-Zeichenfolge manuell wie folgt konstruieren müssen:

SET @SQLQuery = 'SELECT * FROM ' + @TableName + ' WHERE EmployeeID = @EmpID' 

Stellen Sie jedoch sicher, dass Ihre Anwendung erlaubt einem Benutzer nicht direkt den Wert @TableName einzugeben, da dies Ihre Abfrage anfällig für SQL-Injection machen würde. Eine mögliche Lösung hierzu finden Sie unter this answer.

+0

danke aber wie auch immer, ich will das wirklich nicht. kann nicht als Tabellenname an sp_executesql übergeben :( – Neo

+0

@Neo Sie sollten in der Lage sein, 'sp_executesql' zu verwenden, da Sie bereits den richtigen Tabellennamen beim Setzen Ihrer SQL-Zeichenfolge einfügen sollten. Dies ist ein Hauptgrund, warum SQL-Zeichenfolgen sind manuell erstellt an erster Stelle. –

+1

Eine weitere Überlegung ist, auch 'QuoteName' um die Variable anzuwenden. Das wird den Tabellennamen korrekt mit Objektwrappern umhüllen, Standardwerte sind die eckigen Klammern' [...] ' – GoldBishop

3

Versuchen Sie folgendes:

/* Variable Declaration */ 
DECLARE @EmpID AS SMALLINT 
DECLARE @SQLQuery AS NVARCHAR(500) 
DECLARE @ParameterDefinition AS NVARCHAR(100) 
DECLARE @TableName AS NVARCHAR(100) 
/* set the parameter value */ 
SET @EmpID = 1001 
SET @TableName = 'tblEmployees' 
/* Build Transact-SQL String by including the parameter */ 
SET @SQLQuery = 'SELECT * FROM ' + @TableName + ' WHERE EmployeeID = @EmpID' 
/* Specify Parameter Format */ 
SET @ParameterDefinition = '@EmpID SMALLINT' 
/* Execute Transact-SQL String */ 
EXECUTE sp_executesql @SQLQuery, @ParameterDefinition, @EmpID 
+0

definitiv die vollständige Antwort, die ich suchte. –

+0

Brilliant! Mein Problem wurde perfekt gelöst. – Dan

+4

Offen für SQL-Injection. Alles, was Sie tun müssen, ist einen schlechten @TableName-Parameter wie 'sys.databaesses; Alter Server Role sysadmin Mitglied hinzufügen [BadGuy]; - Und da geht dein System. –

21

Zum Schutz vor SQL-Injection versuche ich normalerweise, wo immer möglich Funktionen zu verwenden. In diesem Fall könnten Sie Folgendes tun:

... 
SET @TableName = '<[db].><[schema].>tblEmployees' 
SET @TableID = OBJECT_ID(TableName) --won't resolve if malformed/injected. 
... 
SET @SQLQuery = 'SELECT * FROM ' + OBJECT_NAME(@TableID) + ' WHERE EmployeeID = @EmpID' 
Verwandte Themen