我在尝试在ASP应用程序使用的现有C#类中参数化一些“动态”SQL构建时遇到问题。环境是:
现有代码只是将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>
提前致谢。
答案 0 :(得分:2)
?
是意外令牌的原因是因为您在ORDER BY
子句中使用它(我认为不允许)。
使用参数的原因是为了降低用户输入的风险。在构建查询时,如果ORDER BY
字段和方向不是通过用户输入发送的,则可以安全地构建带有连接的查询。
仅使用?
子句中的WHERE
:
OdbcCommand cmd = new OdbcCommand("SELECT * FROM TABLE_NAME WHERE ID = ? ORDER BY " + sortField + " " + sortDirection);