Ret. Vi kan ikke levere identifikatorer som bindeparametre. Navnet på kolonnen skal være en del af SQL-teksten.
Vi kan dynamisk inkorporere kolonnenavnet i SQL-teksten med noget som dette:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
Og leverer værdier for de to resterende bindeparametre
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
Og du har fuldstændig ret i at være bekymret over SQL Injection.
Leveres som bindeværdier, enkelte anførselstegn i værdierne for attrData
og medname
vil ikke være et problem, hvad angår SQL Injection.
Men det eksempel, jeg har givet er sårbare ved at inkorporere colname
variabel ind i SQL-teksten, hvis vi ikke har nogle garanterede det colname
er "sikker" at inkludere i erklæringen.
Så vi skal lave tildelingen af en værdi til colname
"sikker".
Flere tilgange vi kan bruge gør det. Den mest sikre ville være en "hvidliste"-tilgang. Koden kan sikre, at kun specifikke tilladte "sikre" værdier bliver tildelt colname
, før colname
bliver inkluderet i SQL-teksten.
Som et simpelt eksempel:
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 mere fleksibel tilgang er at sikre, at et backtick-tegn ikke vises i colname
. I eksemplet værdien af colname
bliver undsluppen ved at omslutte det i backticks. Så længe et backtick-tegn ikke vises i colname
, vil vi forhindre, at en angivet værdi fortolkes som andet end som en identifikator.
For en mere generisk (og kompliceret) tilgang til at bruge hardkodede backtick-tegn, kunne vi overveje at bruge supportsQuotedIdentifiers
og getIdentifierQuoteString
metoder til java.sql.DatabaseMetaData
klasse.
(I OP-koden ser vi ikke datatypen for indholdet af attributes
. Vi ser et kald til en metode ved navn replace
, og de argumenter, der er givet hertil. Forudsat at attributes
er en streng, og det formodes at være et kolonnenavn, er det slet ikke klart, hvorfor vi ville have "mellemrum med enkelt anførselstegn" i strengen, eller hvorfor vi skal fjerne det. Bortset fra denne omtale, adresserer dette svar ikke det.)