对,准备好的语句查询参数只能在您使用单个文字值的地方使用.您不能对表名,列名,值列表或任何其他SQL语法使用参数.
所以你必须将你的应用程序变量插入到SQL字符串中,并引用相应的字符串.请使用引号来定界您的表名标识符,并将引号字符串加倍排列:
java.sql.DatabaseMetaData md = conn.getMetaData();
String q = md.getIdentifierQuoteString();
String sql = "SELECT MAX(AGE) FROM %s%s%s";
sql = String.format(sql, q, tablename.replaceAll(q, q+q), q);
例如,如果您的表名字面上是表“名称,并且您的RDBMS标识符引号字符是”,则sql应包含一个字符串,如:
SELECT MAX(AGE) FROM "table""name"
我也同意@ChssPly76的评论 – 最好是你的用户输入实际上不是文字表名称,而是你的代码映射到一个表名,然后插入到SQL查询中的含义.这样可以保证不会发生SQL注入.
HashMap h = new HashMap();
/* user-friendly table name maps to actual, ugly table name */
h.put("accounts", "tbl_accounts123");
userTablename = ... /* user input */
if (h.containsKey(userTablename)) {
tablename = h.get(userTablename);
} else {
throw ... /* Exception that user input is invalid */
}
String sql = "SELECT MAX(AGE) FROM %s";
/* we know the table names are safe because we wrote them */
sql = String.format(sql, tablename);