【问题标题】:How to parameterise table name in ODBC query如何在 ODBC 查询中参数化表名
【发布时间】:2012-12-17 13:45:17
【问题描述】:

我有一个到数据库的 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);

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

【问题讨论】:

    标签: c# asp.net sql-server odbc


    【解决方案1】:

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

    一些提示:

    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
        }
    }
    

    【讨论】:

    • 谢谢!但不幸的是,我无权访问数据库来添加诸如 SP 之类的东西,所以我需要在应用程序中完成这一切。但这是一个有趣的解决方案。另外,像 troyhunt.com/2012/12/stored-procedures-and-orms-wont-save.html 这样的内容是否适用于您的解决方案?
    • 在您提供的链接中,EXEC(@query) 在 SQL 存储过程中被调用,在使用 @SearchTerm 参数构建动态查询之后。因此,SQL 开发人员还应该注意他们实际使用数据的方式以及动态查询的风险。
    • 刚刚看到您的编辑,似乎是最简单的方法,即使它稍微不那么优雅。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    相关资源
    最近更新 更多