E 'possibile utilizzare la concatenazione per creare la vostra stringa. Ciò non causa l'avviso di sicurezza.Ed è preferibile per chiarezza quando si tratta di istruzioni SQL lunghe che potrebbero essere meglio suddivise su più righe
L'utilizzo delle variabili per costruire la stringa è ciò che causa l'avviso di sicurezza.
Ciò causerà l'avvertimento:
String columnName = getName();
String tableName = getTableName();
final String sql = "SELECT MAX(" + columnName + ") FROM " + tableName;
PreparedStatement ps = connection.prepareStatement(sql);
Non non funziona:
String columnName = getName();
String tableName = getTableName();
final String sql = "SELECT MAX(" + "?" + ")" +
"FROM " + "?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, columnName);
ps.setString(2, tableName);
Non funziona perché le dichiarazioni preparate consentono solo parametri da rilegare per "valori" bit del Istruzione SQL.
Questa è la soluzione che funziona:
private static final boolean USE_TEST_TABLE = true;
private static final boolean USE_RESTRICTED_COL = true;
private static final String TEST_TABLE = "CLIENT_TEST";
private static final String PROD_TABLE = "CLIENT";
private static final String RESTRICTED_COL ="AGE_COLLATED";
private static final String UNRESTRICTED_COL ="AGE";
....................
final String sql = "SELECT MAX(" +
(USE_RESTRICTED_COL ? RESTRICTED_COL : UNRESTRICTED_COL) + ")" +
"FROM " +
(USE_TEST_TABLE ? TEST_TABLE : PROD_TABLE);
PreparedStatement ps = connectComun.prepareStatement(sql);
ma funziona solo se si dispone di scegliere tra due tabelle i cui nomi sono noti al momento della compilazione. È possibile utilizzare operatori ternari composti per più di 2 casi, ma diventa illeggibile.
Il primo caso potrebbe essere un problema di sicurezza se getName() o getTableName() ottiene il nome da fonti non attendibili.
È abbastanza possibile creare un'istruzione SQL sicura utilizzando le variabili se tali variabili sono state precedentemente verificate. Questo è il tuo caso, ma FindBugs non riesce a capirlo. Findbugs non è in grado di sapere quali fonti sono attendibili o meno.
Ma se è necessario utilizzare un nome di colonna o tabella dall'utente o un input non affidabile, non c'è modo di aggirarlo. Devi verificare te stesso tale stringa e ignorare l'avviso di Findbugs con uno dei metodi proposti in altre risposte.
Conclusione: Non esiste una soluzione perfetta per il caso generale di questa domanda.
Ciao utente714965, grazie per la risposta. Ho altre occorrenze di questo avviso usando StringBuilder, in modo che non funzioni. L'annotazione funziona (è bene chiarire ad altri lettori che il suo nome completo è @ edu.umd.cs.findbugs.annotations.SuppressWarnings). Ora devo decidere se voglio la lib di FindBug nel mio progetto o no. Grazie ancora. – ederribeiro
@ederribeiro: una dipendenza da FindBugs dal tuo progetto potrebbe non essere la migliore che hai ragione. Nella mia risposta originale ho perso un punto, per favore vedi l'ultimo paragrafo. – Kai
Questo risolve questo particolare problema perché OP è sicuro che il suo codice è sicuro da SQL INJECTION. Ma è soggetto a errori e quindi una cattiva pratica in generale. Le dichiarazioni preparate con parametri sono la strada da percorrere. Non voterò negativo dato che in realtà risolve la domanda ma consiglio di non farlo in quel modo. –