Rätt. Vi kan inte tillhandahålla identifierare som bindningsparametrar. Namnet på kolumnen måste vara en del av SQL-texten.
Vi kan dynamiskt infoga namnet på kolumnen i SQL-texten med något så här:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
Och tillhandahålla värden för de två återstående bindningsparametrarna
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
Och du har helt rätt när det gäller att vara orolig för SQL Injection.
Levereras som bindningsvärden, enkla citattecken i värdena för attrData
och medname
kommer inte att vara ett problem när det gäller SQL Injection.
Men exemplet jag har gett är sårbara genom att införliva colname
variabel i SQL-texten, om vi inte har något garanterat det colname
är "säkert" att inkludera i uttalandet.
Så vi måste göra tilldelningen av ett värde till colname
"säkert".
Flera metoder vi kan använda gör det. Det säkraste skulle vara en "vitlista". Koden kan säkerställa att endast specifika tillåtna "säkra" värden tilldelas colname
, före colname
inkluderas i SQL-texten.
Som ett enkelt exempel:
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
}
En mer flexibel metod är att se till att ett backtick-tecken inte visas i colname
. I exemplet, värdet på colname
håller på att rymmas genom att omsluta den i backticks. Så länge som ett backtick-tecken inte visas i colname
, kommer vi att förhindra att ett tillhandahållet värde tolkas som något annat än som en identifierare.
För ett mer allmänt (och komplicerat) tillvägagångssätt för att använda hårdkodade backtick-tecken kan vi överväga att använda supportsQuotedIdentifiers
och getIdentifierQuoteString
metoder för java.sql.DatabaseMetaData
klass.
(I OP-koden ser vi inte datatypen för innehållet i attributes
. Vi ser ett anrop till en metod som heter replace
, och de argument som tillhandahålls för det. Förutsatt att attributes
är en sträng, och det är tänkt att vara ett kolumnnamn, det är inte alls klart varför vi skulle ha "mellanslag enstaka citattecken" i strängen, eller varför vi behöver ta bort det. Förutom detta omnämnande tar det här svaret inte upp det.)