#c# #odbc #informix #parameterized-query
#c# #asp.net #sql-сервер #odbc
Вопрос:
У меня есть подключение ODBC к базе данных, и я хотел бы, чтобы пользователь мог просматривать данные в любой таблице. Поскольку это ASP.net приложение Я не могу быть уверен, что отправленное имя таблицы также не содержит неприятностей. Я пытался использовать параметризованный запрос, но я всегда получаю сообщение об ошибке, в котором говорится, что я «Должен объявить переменную таблицы» — это кажется проблемой, потому что это имя таблицы
string sql = "SELECT TOP 10 * FROM ? ";
OdbcCommand command = new OdbcCommand(sql, dbConnection);
command.Parameters.Add(new OdbcParameter("@table", tableName));
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(tableData);
Каков наилучший способ добиться этого безопасным способом?
Ответ №1:
Используйте хранимую процедуру, это самый безопасный способ.
Некоторые подсказки:
- Вероятно, вы также можете использовать объекты
System.Data.SqlClient
пространства имен - Заключите инициализации ваших объектов connection, command и adapter в
using
инструкции
Вот простой пример:
string sqlStoredProcedure = "SelectFromTable";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
using (OdbcCommand command = new OdbcCommand(sqlStoredProcedure, dbConnection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new OdbcParameter("@table", tableName));
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
Другим способом было бы получить все имена таблиц и проверить tableName
строковую переменную как запись в списке, возможно, используя:
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
Вот простая реализация, основанная на вашем сценарии:
string sql = "SELECT TOP 10 * FROM {0}";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
var matches = tables.Select(String.Format("TABLE_NAME = '{0}'", tableName));
//check if table exists
if (matches.Count() > 0)
{
using (OdbcCommand command = new OdbcCommand(String.Format(sql, tableName), dbConnection))
{
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
else
{
//handle invalid value
}
}
Комментарии:
1. Спасибо! Но, к сожалению, у меня нет доступа к базе данных для добавления таких вещей, как SP, поэтому мне нужно сделать все это в приложении. но это интересное решение. Кроме того, было бы что-то вроде этого troyhunt.com/2012/12/stored-procedures-and-orms-wont-save.html применить к вашему решению?
2. В указанной вами ссылке
EXEC(@query)
вызывается хранимая процедура SQL после создания динамического запроса с использованием@SearchTerm
параметра. Итак, разработчики SQL также должны позаботиться о том, как они на самом деле используют данные и каковы риски динамических запросов.3. Только что видел ваше редактирование, кажется, это самый простой способ сделать это, даже если он немного менее элегантный. Спасибо за вашу помощь!