правилно. Не можем да предоставим идентификатори като параметри за свързване. Името на колоната трябва да е част от SQL текста.
Можем динамично да включим името на колоната в SQL текста с нещо подобно:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
И предоставя стойности за двата оставащи параметъра на свързване
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
И вие сте напълно прав, че сте загрижени за SQL инжекцията.
Предоставя се като стойности за свързване, единични кавички в стойностите на attrData
и medname
няма да е проблем по отношение на SQL инжекцията.
Но примерът, който предоставих е уязвим чрез включване на colname
променлива в SQL текста, ако нямаме гарантирано това colname
е „безопасно“ за включване в изявлението.
Така че трябва да направим присвояване на стойност на colname
„безопасен“.
Няколко подхода, които можем да използваме за това. Най-сигурният би бил подходът на "белия списък". Кодът може да гарантира, че само определени разрешени "безопасни" стойности се присвояват на colname
, преди colname
се включва в SQL текста.
Като прост пример:
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
}
По-гъвкав подход е да се гарантира, че знак за обратна отметка не се появява в colname
. В примера стойността на colname
се избяга като го оградите в обратни точки. Така че, стига символ за обратна отметка да не се появи в colname
, ще предотвратим тълкуване на предоставена стойност като нещо различно от идентификатор.
За по-общ (и сложен) подход към използването на твърдо кодирани знаци за обратна отметка, бихме могли да обмислим използването на supportsQuotedIdentifiers
и getIdentifierQuoteString
методи на java.sql.DatabaseMetaData
клас.
(В OP кода не виждаме типа данни на съдържанието на attributes
. Виждаме извикване на метод с име replace
, и аргументите, които са предоставени за това. Ако приемем, че attributes
е низ и това би трябвало да е име на колона, изобщо не е ясно защо ще имаме "пространство в единични кавички" в низа или защо трябва да го премахнем. Освен това споменаване, този отговор не се занимава с това.)