I\'ve been looking around for a way to enter a variable table name and it seems the best way is to use dynamic sql, although it can lead to SQL injection. Can anyone demonst
It seems that you have to use dynamic SQL, which basically means you're going to have to concatenate the table name into a query string and run it through the 'sp_executesql' stored procedure in TSQL.
Using SqlCommand is not dynamic SQL. Although you are dynamically building an SQL string, you are still running a plain old SQL string in the end.
To do so safely and project against SQL injection, you must ensure the table name is valid, and you must do so yourself through any means necessary. Fortunately, you have 3 good options, one of which is very easy and virtually fool-proof.
As others have mentioned, you could:
I had a similar question about dropping a table by name, and that's where the QUOTENAME function was mentioned: https://stackoverflow.com/a/19528324/88409
To use dynamic SQL, you would actually have to do something like this:
string sql =
"declare @query nvarchar(max) = 'SELECT * FROM ' + QUOTENAME(@tablename) + ' WHERE ' + QUOTENAME(@columnname) + ' = @cv'; " +
"declare @params nvarchar(500) = N'@cv nvarchar(500)'; " +
"exec sp_executesql @query, @params, @cv=@columnvalue;";
SqlCommand command = new SqlCommand( sql, conn );
command.Parameters.AddWithValue( "@tablename", tableName );
command.Parameters.AddWithValue( "@columnname", columnName );
command.Parameters.AddWithValue( "@columnvalue", columnValue );
If by chance the SqlCommand class doesn't support such a complex query with 'declare' statements, then you'll need to just move the value of the 'sql' string into a stored procedure that takes those same three parameters then call it by name by setting the SqlCommand.CommandType to StoredProcedure like so:
SqlCommand command = new SqlCommand( "MyStoredProcedureName", conn );
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue( "@tablename", tableName );
command.Parameters.AddWithValue( "@columnname", columnName );
command.Parameters.AddWithValue( "@columnvalue", columnValue );