Dobrze. Nie możemy dostarczyć identyfikatorów jako parametrów wiązania. Nazwa kolumny musi być częścią tekstu SQL.
Możemy dynamicznie włączyć nazwę kolumny do tekstu SQL za pomocą czegoś takiego:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
I podaj wartości dla dwóch pozostałych parametrów wiązania
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
I masz całkowitą rację, jeśli chodzi o obawy związane z wstrzykiwaniem SQL.
Dostarczane jako wartości wiązania, pojedyncze cudzysłowy w wartościach attrData i medname nie będzie problemem, jeśli chodzi o wstrzykiwanie SQL.
Ale podany przeze mnie przykład to podatny na ataki poprzez włączenie colname zmienną do tekstu SQL, jeśli nie mamy gwarancji, że colname jest „bezpieczny” do umieszczenia w oświadczeniu.
Musimy więc dokonać przypisania wartości do colname "bezpieczny".
Możemy to zrobić na kilka sposobów. Najbezpieczniejszym byłoby podejście „białej listy”. Kod może zapewnić, że tylko określone dozwolone „bezpieczne” wartości zostaną przypisane do colname , przed colname zostaje uwzględniony w tekście SQL.
Jako prosty przykład:
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
}
Bardziej elastycznym podejściem jest upewnienie się, że znak wsteczny nie pojawia się w colname . W tym przykładzie wartość colname jest uciekana umieszczając go w backtickach. Tak długo, jak znak cofania nie pojawia się w colname , zapobiegniemy interpretacji podanej wartości jako czegoś innego niż identyfikator.
Aby uzyskać bardziej ogólne (i skomplikowane) podejście do używania zakodowanych na stałe znaków backtick, możemy rozważyć użycie supportsQuotedIdentifiers i getIdentifierQuoteString metody java.sql.DatabaseMetaData klasa.
(W kodzie OP nie widzimy typu danych zawartości attributes . Widzimy wywołanie metody o nazwie replace i argumenty, które są do tego dostarczone. Zakładając, że attributes jest ciągiem i ma to być nazwa kolumny, nie jest wcale jasne, dlaczego mielibyśmy mieć w ciągu „spację w pojedynczym cudzysłowie” ani dlaczego musimy ją usunąć. Poza tą wzmianką ta odpowiedź nie dotyczy tego.)