如何使用C#参数化DB2 ODBC查询?

时间:2012-04-26 20:37:36

标签: c# odbc db2

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

  • Win Server 2008
  • .NET 3.0
  • C#
  • DB2 9.x([IBM] [CLI驱动程序] [DB2])

现有代码只是将SQL与长SQL字符串中的param字符串连接起来 - 这当然存在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当然是我要查询的表格。

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

  

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

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

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

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

我所看到的东西向我表明“?”参数未被替换。

我尝试过AddWithValue(),我尝试过Add(OdbcType.VarChar).Value = sortField(或其他类似的东西)。

我很喜欢这个 - 所有的谷歌搜索和搜索都向我表明上面的代码应该可以工作,但到目前为止我还没有能够用变量替换SQL中的参数。 / p>

提前致谢。

1 个答案:

答案 0 :(得分:2)

?是意外令牌的原因是因为您在ORDER BY子句中使用它(我认为不允许)。

使用参数的原因是为了降低用户输入的风险。在构建查询时,如果ORDER BY字段和方向不是通过用户输入发送的,则可以安全地构建带有连接的查询。

仅使用?子句中的WHERE

OdbcCommand cmd = new OdbcCommand("SELECT * FROM TABLE_NAME WHERE ID = ? ORDER BY " + sortField + " " + sortDirection);