Prawidłowe, przygotowane parametry zapytania do wyciągu mogą być używane tylko wtedy, gdy użyjemy pojedynczej literalnej wartości o wartości. Nie można użyć parametru dla nazwy tabeli, nazwy kolumny, listy wartości ani żadnej innej składni SQL.
Musisz więc interpolować zmienną aplikacji do łańcucha SQL i odpowiednio zacytować ciąg. Używaj cytując do wytyczają swój identyfikator nazwa tabeli i uciec ciąg cytat podwojenie go:
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);
Na przykład, jeśli nazwa tabeli jest dosłownie table"name
, a RDBMS identyfikator cytat postać jest "
, następnie sql
powinien zawierać ciąg jak:
SELECT MAX(AGE) FROM "table""name"
zgadzam się również z użytkownika @ ChssPly76 komentarza - najlepiej, jeśli dane wejściowe użytkownika nie jest właściwie dosłowne nazwa tabeli, ale znaczącym, że kod mapy do nazwy tabeli, który cię następnie inter polate do zapytania SQL. Zapewnia to większą pewność, że nie wystąpi iniekcja SQL.
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);
Jeśli nazwa tabeli pochodzi bezpośrednio ** ** od danych wprowadzonych przez użytkownika, masz dużo większe problemy niż martwić się o swoją odkażania SQL (a jeśli nie ma nic do dezynfekcji) – ChssPly76