Les paramètres de requête de requête préparés à droite peuvent être utilisés uniquement lorsque vous utilisez une valeur littérale unique . Vous ne pouvez pas utiliser un paramètre pour un nom de table, un nom de colonne, une liste de valeurs ou toute autre syntaxe SQL.
Vous devez donc interpoler votre variable d'application dans la chaîne SQL et la citer correctement. N'utiliser citant pour délimiter l'identifiant de votre nom de la table, et échapper à la chaîne de citation en le doublant:
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);
Par exemple, si votre nom de la table est littéralement table"name
, et votre identifiant SGBDR guillemet est "
, puis sql
doit contenir une chaîne comme:
SELECT MAX(AGE) FROM "table""name"
Je suis également d'accord avec le commentaire de @ ChssPly76 - il est préférable que votre entrée utilisateur est en fait pas le nom de la table littérale, mais un signifiant que votre code cartes dans un nom de table, que vous alors inter polate dans la requête SQL. Cela vous donne plus d'assurance qu'aucune injection SQL ne peut avoir lieu.
HashMap h = new HashMap<String,String>();
/* 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);
Si le nom de la table est directement ** ** de l'entrée utilisateur, vous avez des problèmes beaucoup plus importants à vous soucier de votre SQL désinfectante (et si elle ne il n'y a rien à aseptiser) – ChssPly76