我在尝试参数化ASP应用程序使用的现有C#类中的某些“动态”SQL构建时遇到了问题。环境是:如何使用C#参数化DB2 ODBC查询?
- 赢服务器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秒ERROR [42601] [IBM] [CLI 驱动程序] [ DB2] SQL0104N在“”之后发现了一个意外的令牌“?” 预期令牌可能包括:“MICROSECONDS MICROSECOND SECONDS SECOND MINUTES MINUTE HOURS”SQLSTATE = 42601 at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)连接驱动程序= {IBM DB2 ODBC DRIVER}; .....
不允许将其更改为存储过程。
不允许升级到更高版本的.NET。
不允许更改/升级ODBC驱动程序。
我所看到的告诉我,“?”参数未被替换。
我已经尝试过AddWithValue(),我试过添加(OdbcType.VarChar).Value = sortField(或者那个效果)。
我很善于处理我的问题 - 所有的搜索和搜索都表明我上面的代码应该可以工作,但到目前为止我还没有能够用SQL中的参数替换变量。
在此先感谢。
哦,我已经尝试了 “新OdbcParameter(......)” 太。 – 2012-04-26 20:45:28
我不相信你正在尝试的是真实的参数。 “FieldName =?”是一个参数。在这种情况下,您将构建查询为:“... ORDER BY”+ sortField +“”+ sortDirection – Quintium 2012-04-26 20:46:10
不是SQL参数,而是将C#参数替换为SQL以防止SQL注入。我的例子是简化的,但真正的查询包含用户可以输入的字符串。我想保护SQL,防止父母给孩子起名为“Bobby Tables”(“Robert”); DROP TABLE Students; - “)。 – 2012-04-26 20:49:37