1

我在尝试参数化 ASP 应用程序使用的现有 C# 类中的一些“动态”SQL 构建时遇到问题。环境是:

  • 赢服务器 2008
  • .NET 3.0
  • C#
  • DB2 9.x([IBM][CLI 驱动程序][DB2])

现有代码只是将 SQL 与长 SQL 字符串中的参数字符串连接起来——这当然存在 SQL 注入的风险。每当我看到这一点时,我的做法就是,我倾向于更改代码以使用参数。但是使用此代码我失败了。我试过“@”,也试过“?” - 后者是我理解的 ODBC 所必需的。

这是我编译并运行的简化代码片段(如果我的格式不正确,请原谅我 - 这是我的第一个问题):

private DataSet test(String schemaName )
{
        String sortField = "TABLE_NAME.COLUMN_NAME";
        String sortDirection = "ASC";
        OdbcConnection conn = new OdbcConnection();
        DataSet ds = new DataSet();

        string connStr = ConfigurationManager.AppSettings[schemaName] + dbUser;
        try
        {
            conn.ConnectionString = connStr;
            OdbcCommand cmd = new OdbcCommand("SELECT * FROM TABLE_NAME ORDER BY ? ? ");
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.Parameters.Add(sortField);
            cmd.Parameters.Add(sortDirection);                              
            logger.log("cmd SQL = \t" + cmd.CommandText );

            OdbcDataAdapter da = new OdbcDataAdapter(cmd);
            da.Fill(ds);

            return ds;
        }
        catch (Exception ex)
        {
            ex.Data.Add("Location:", "test()");
            ex.Data.Add("Connection", conn.ConnectionString);
            logger.logException(ex);
            throw ex;
        }
        finally
        {
            conn.Close();
        }
    }

日志打印输出:

cmd SQL = SELECT * FROM TABLE_NAME ORDER BY ? ?

其中 TABLE_NAME 当然是我要查询的表。

我得到的回报是(删除了一些专有信息:

异常发生在 2012 年 4 月 26 日下午 12:29:41 错误 [42601] [IBM][CLI 驱动程序][DB2] SQL0104N 意外标记“?” 在“”之后发现。预期的令牌可能包括:“MICROSECONDS MICROSECOND SECONDS SECOND MINUTES MINUTE HOURS”。SQLSTATE=42601 at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)Connection Driver={IBM DB2 ODBC DRIVER}; ......

不允许将此更改为存储过程。

不允许升级到更高版本的 .NET。

不允许更改/升级 ODBC 驱动程序。

我所看到的向我表明“?” 参数没有被替换。

我已经尝试过 AddWithValue() 并且我已经尝试过 Add(OdbcType.VarChar).Value = sortField (或类似的东西)。

我有点走投无路了——所有的谷歌搜索和搜索都向我表明上面的代码应该可以工作,但到目前为止,我还无法将 SQL 中的参数替换为变量。

提前致谢。

4

1 回答 1

2

?是一个意外标记的原因是因为您在ORDER BY子句中使用它(我认为这是不允许的)。

使用参数的原因是为了减轻用户输入的风险。在构建查询时,如果ORDER BY字段和方向不是通过用户输入来的,那么您可以安全地通过连接构建查询。

?WHERE子句中使用:

OdbcCommand cmd = new OdbcCommand("SELECT * FROM TABLE_NAME WHERE ID = ? ORDER BY " + sortField + " " + sortDirection);
于 2012-04-26T20:46:42.150 回答