Edit: I marked that the linked question was useful, but I didn't intend to mean that it completely answered my question here, which after reviewing others' comments and answers here, I realize I need two different escaped versions of table
, one as a safe single-quoted identifier, and one as a safe single-bracketed identifier.
I need to drop a SQL server table from C# with the table name as a parameter.
This is my code:
private static void DropSqlTableIfExists(string connectionString, string table)
{
string query = "if object_id (@table, 'U') is not null begin drop table @table; end";
using SqlConnection conn = new(connectionString);
using SqlCommand command = new(query, conn);
command.Parameters.AddWithValue("@table", table);
conn.Open();
command.ExecuteNonQuery();
}
The above code gives me an error, Incorrect syntax near '@table'.
I could of course put the table name directly into the query
string, but that would allow code injection, which I need to avoid.
What is the best way to go about this?
EDIT 2:
Based on feedback, I updated the code to look like this:
private static void DropSqlTableIfExists(string connectionString, string table)
{
string tableSafeQuoted = $"'{table.Replace("'", "''")}'";
string tableSafeBracketed = $"[{table.Replace("]", "]]").Replace(".", "].[")}]";
string query = $"if object_id ({tableSafeQuoted}, 'U') is not null begin drop table {tableSafeBracketed}; end";
using SqlConnection conn = new(connectionString);
using SqlCommand command = new(query, conn);
conn.Open();
command.ExecuteNonQuery();
}
tbh, I'm not sure if it's 100% safe, due to the oddity of the .
replacement.. but I think unless someone gives me a good reason not to, I will leave it like this..