1

我有一个到数据库的 ODBC 连接,我希望用户能够查看任何表中的数据。由于这是一个 ASP.net 应用程序,我不能相信发送的表名也不包含 nasties。我曾尝试使用参数化查询,但我总是收到一条错误消息,提示我“必须声明表变量”——这似乎是一个问题,因为它是表名

 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);

以安全的方式实现这一目标的最佳方法是什么?

4

1 回答 1

2

使用存储过程,这是最安全的方法。

一些提示:

  1. 您可能还可以使用System.Data.SqlClient命名空间对象
  2. 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
    }
}
于 2012-12-17T13:50:35.290 回答