Я пытаюсь заставить следующий код работать:
String connStr = sqlRoutines.connectionString;
SqlConnection sqlConn = new SqlConnection(connStr);
sqlConn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM TABEL=@tabel";
cmd.Parameters.Add("@tabel", SqlDbType.Text).Value = DataContainer.sqlTabel;
SqlDataReader reader = cmd.ExecuteReader();
Console.WriteLine(reader.FieldCount.ToString());
reader.Close();
sqlConn.Close();
Так или иначе, значение "DataContainer.sqlTabel" не добавляется в команду. Я что-то упустил?
Всякий раз, когда я использую cmd.CommandText = "SELECT * FROM" + DataContainer.sqlTabel;
все работает нормально. Однако я хочу избежать этого метода из-за SQL Injection.
Заранее спасибо!
РЕДАКТИРОВАТЬ:
Я хочу получить команду, которая использует переменную (которая изменяется пользователем). Поэтому я хочу иметь что-то вроде этого: SELECT * FROM * a variable defined by the use *;
, Когда я использую:
cmd.CommandText = "SELECT * FROM @tablename";
cmd.Parameters.Add("@tablename", SqlDbType.Text).Value = DataContainer.sqlTabel;
Это не работает.
Я думаю, вы пытаетесь параметризовать имя таблицы, которое вы не можете. Я тоже не понимаю, что такое TABEL
. FROM
(Transact-SQL) не имеет такого синтаксиса.
Вы можете только параметризовать значения. Не имена таблиц или имена столбцов. Укажите имя таблицы как часть SQL. Но когда вы это делаете, вам нужно очень сильную проверку имени таблицы перед тем, как поместить ее в SQL, или иметь белый список допустимых имен таблиц, чтобы избежать атак SQL-инъекций.
Если вы действительно хотите параметризовать его, вы можете использовать (но не рекомендуется) динамический SQL.
Как мы видели, мы можем сделать эту процедуру работать с помощью динамического SQL, но также должно быть ясно, что мы не получаем никаких преимуществ при создании этого динамического SQL в хранимой процедуре. Вы также можете отправить динамический SQL с клиента. Итак, ОК: 1) если оператор SQL очень сложный, вы сохраняете некоторый сетевой трафик и инкапсулируете. 2) Как мы видели, начиная с SQL 2005 существуют методы решения разрешений. Тем не менее, это плохая идея.
Также using
инструкцию using
для установки соединений с базой данных.
using(SqlConnection sqlConn = new SqlConnection(connStr))
using(SqlCommand cmd = sqlConn.CreateCommand())
{
...
...
using(SqlDataReader reader = cmd.ExecuteReader())
{
...
}
}
cmd.CommandText = "SELECT * FROM " + DataContainer.sqlTabel;
работает отлично. Я предложил такой способ, но это была строгая проверка на стороне пользователя или белый список имен таблиц.
Вы не можете этого сделать. Вы можете использовать только динамический SQL. Вы должны сами решить, является ли SQL-инъекция риском, и поэтому вам нужно закодировать это, возможно, проверяя, что значение таблицы не содержит ничего, кроме действительного имени таблицы. Вы можете проверить имя таблицы на системные таблицы, чтобы убедиться, что она действительна.
мы не можем использовать параметры для имени таблицы или имени столбца. параметры ограничены только значениями. если вы хотите использовать параметр для имени таблицы, тогда вы должны создать хранимую процедуру, а затем передать имя таблицы в качестве параметра для сохранения процедуры. Более подробную информацию можно найти здесь