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.)