Как использовать параметры в SQL-запросе с именем столбца

#c# #sql #sql-server #datacolumn

#c# #sql #sql-сервер #datacolumn

Вопрос:

У меня есть следующий SQL-запрос, который берет заголовок из файла и создает столбец с тем же именем, что и заголовок:

 SqlCommand createtable = new SqlCommand("CREATE TABLE "   tbXLSTableName.Text   " ("   dc.ColumnName   " varchar(MAX))", myConnection);
  

Он открыт для атаки с использованием SQL-инъекций, поэтому я решил использовать такие параметры:

 string strCreateTable = "CREATE TABLE @TableNameCreateXLS ("   dc.ColumnName   " varchar(MAX))";

SqlCommand createtable = new SqlCommand(strCreateTable, myConnection);      
createtable.Parameters.AddWithValue("TableNameCreateXLS", tbXLSTableName.Text);
  

dc является DataColumn объектом.

Я получаю следующую ошибку:

Incorrect syntax near @TableNameCreateXLS

Как я могу устранить ошибку?

Комментарии:

1. Как я уже сказал в комментарии к вашему предыдущему (теперь удаленному) вопросу: «Обычно вы не можете параметризовать имена таблиц и столбцов».

2. Он был удален случайно, и я потерял страницу для восстановления. Итак, используйте старую команду, которую я использовал?

3. ДА. Но сначала проверьте значение, в идеале, действительно сильно ограничивая его. (В тех случаях, когда вы хотите выбрать из нескольких таблиц, используйте белый список — здесь это, конечно, не работает.)

4.сначала проверьте значение:-) 🙂 🙂

5. ВЗДОХ , это просто не кьюл.

Ответ №1:

Вы не можете использовать параметры для имени таблицы и имен столбцов, но вы можете использовать SqlCommandBuilder.QuoteIdentifier метод для экранирования их значений. Нравится:

 SqlCommandBuilder sqlBuilder = new SqlCommandBuilder();
string columnName = dc.ColumnName;//"somecolumn"
string TableNameCreateXLS = "someTable";
string escapedColumnName = sqlBuilder.QuoteIdentifier(columnName);
string escpaedTableName = sqlBuilder.QuoteIdentifier(TableNameCreateXLS);

string strCreateTable = string.Format("CREATE TABLE {0} ({1} varchar(MAX))",escpaedTableName, escapedColumnName);
  

Ответ №2:

К сожалению, вы не можете использовать параметры для имен таблиц. Обычно я вижу, что это делается, когда люди хотят запросить динамическую таблицу, и в таких случаях я говорю, что безопаснее всего запросить таблицу имен таблиц с помощью параметра, но в вашем случае это не работает.

Так что, помимо очистки ввода имени таблицы самостоятельно, я не думаю, что у вас есть какой-либо встроенный в SQL способ сделать это безопасно. Если динамическое создание таблицы таким образом неизбежно, то, по крайней мере, обязательно очистите первую.

Комментарии:

1. Каков наилучший способ очистки текстового поля для имени таблицы. Любой метод SQL?

2. @SiKni8 По общему признанию, я не знаю хорошего способа сделать это вручную. Почти универсальный совет — использовать параметризованные запросы, но здесь это действительно не работает. По крайней мере, удалите ‘ (апострофы). Вы уверены, что хотите предоставить пользователю прямой доступ с помощью текстового поля для создания любой таблицы, которую они хотят?

3. Хорошей новостью является то, что приложение будет использоваться внутри нашей группы. Плохая новость в том, что любой может быть злым в любое время ;). Я разрешаю только БУКВЕННО-ЦИФРОВОЕ значение для текстового поля, поэтому все должно быть в порядке.

Ответ №3:

Используйте это и посмотрите, работает ли это:

 createtable.Parameters.AddWithValue("@TableNameCreateXLS", tbXLSTableName.Text);