Recht. Wir können keine Bezeichner als Bindungsparameter bereitstellen. Der Name der Spalte muss Teil des SQL-Textes sein.
Wir können den Namen der Spalte wie folgt dynamisch in den SQL-Text einbauen:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
Und liefern Sie Werte für die beiden verbleibenden Bindungsparameter
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
Und Sie haben absolut Recht, wenn Sie sich Sorgen über SQL Injection machen.
Als Bindungswerte geliefert, einfache Anführungszeichen in den Werten von attrData
und medname
wird in Bezug auf SQL Injection kein Problem sein.
Aber das Beispiel, das ich bereitgestellt habe, ist ist angreifbar durch Einbindung des colname
Variable in den SQL-Text, wenn wir nicht garantiert haben, dass colname
in die Aussage "sicher" aufgenommen werden kann.
Wir müssen also colname
einen Wert zuweisen "sicher".
Dazu können wir mehrere Ansätze verwenden. Am sichersten wäre ein „Whitelist“-Ansatz. Der Code kann sicherstellen, dass colname
nur bestimmte zulässige "sichere" Werte zugewiesen werden , vor colname
wird in den SQL-Text eingefügt.
Als einfaches Beispiel:
String colname;
if (attributes.equals("someexpectedvalue") {
colname = "columnname_to_be_used";
} else if (attributes.equals("someothervalid") {
colname = "valid_columname";
} else {
// unexpected/unsupported attributes value so
// handle condition or throw an exception
}
Ein flexiblerer Ansatz besteht darin sicherzustellen, dass in colname
kein Backtick-Zeichen erscheint . Im Beispiel der Wert von colname
wird escaped indem Sie es in Backticks einschließen. Solange also kein Backtick-Zeichen in colname
vorkommt , verhindern wir, dass ein bereitgestellter Wert als etwas anderes als als eine Kennung interpretiert wird.
Für einen allgemeineren (und komplizierteren) Ansatz zur Verwendung von hartcodierten Backtick-Zeichen könnten wir die Verwendung von supportsQuotedIdentifiers
in Betracht ziehen und getIdentifierQuoteString
Methoden von java.sql.DatabaseMetaData
Klasse.
(Im OP-Code sehen wir den Datentyp des Inhalts von attributes
nicht . Wir sehen einen Aufruf einer Methode namens replace
, und die Argumente, die dazu geliefert werden. Angenommen, dass attributes
ein String ist, und das soll ein Spaltenname sein, ist es überhaupt nicht klar, warum wir "space single quote space" im String haben oder warum wir das entfernen müssen. Abgesehen von dieser Erwähnung geht diese Antwort darauf nicht ein.)