I parametri di query dell'istruzione a destra e preparati possono essere utilizzati solo dove si utilizza un valore letterale singolo. Non è possibile utilizzare un parametro per un nome di tabella, un nome di colonna, un elenco di valori o qualsiasi altra sintassi SQL.
Quindi è necessario interpolare la variabile dell'applicazione nella stringa SQL e citare la stringa in modo appropriato. Non utilizzare citando per delimitare l'identificatore nome della tabella, e la fuga la stringa di citazione raddoppiando esso:
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);
Ad esempio, se il nome della tabella è letteralmente table"name
, e il tuo personaggio identificatore citazione RDBMS è "
, allora sql
dovrebbe contenere una stringa come:
SELECT MAX(AGE) FROM "table""name"
sono anche d'accordo con @ di ChssPly76 commento - è meglio se l'input utente non è in realtà il nome della tabella letterale, ma un significante che il codice associa in un nome di tabella, che si allora inter polare nella query SQL. Questo ti dà una maggiore sicurezza che nessuna iniezione SQL può verificarsi.
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);
fonte
2009-11-05 00:28:14
Se il nome della tabella viene ** ** direttamente dall'input dell'utente, hai problemi molto più grandi di cui preoccuparsi che sanificazione SQL (e se non c'è niente da disinfettare) – ChssPly76