Benar. Kami tidak dapat menyediakan pengidentifikasi sebagai parameter pengikatan. Nama kolom harus menjadi bagian dari teks SQL.
Kita dapat secara dinamis memasukkan nama kolom ke dalam teks SQL dengan sesuatu seperti ini:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
Dan berikan nilai untuk dua parameter pengikatan yang tersisa
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
Dan Anda benar sekali tentang kekhawatiran tentang SQL Injection.
Disediakan sebagai nilai pengikatan, tanda kutip tunggal dalam nilai attrData
dan medname
tidak akan menjadi masalah, dalam hal SQL Injection.
Tapi contoh yang saya berikan adalah rentan dengan memasukkan colname
variabel ke dalam teks SQL, jika kita tidak memiliki jaminan bahwa colname
"aman" untuk disertakan dalam pernyataan.
Jadi kita perlu membuat penetapan nilai ke colname
"aman".
Beberapa pendekatan yang dapat kita gunakan untuk melakukan itu. Yang paling aman adalah pendekatan "daftar putih". Kode dapat memastikan bahwa hanya nilai "aman" tertentu yang diizinkan yang ditetapkan ke colname
, sebelum colname
dimasukkan ke dalam teks SQL.
Sebagai contoh sederhana:
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
}
Pendekatan yang lebih fleksibel adalah memastikan bahwa karakter backtick tidak muncul di colname
. Pada contoh, nilai colname
sedang melarikan diri dengan melampirkannya di backticks. Jadi, selama karakter backtick tidak muncul di colname
, kami akan mencegah nilai yang diberikan diinterpretasikan sebagai apa pun selain sebagai pengenal.
Untuk pendekatan yang lebih umum (dan rumit) dalam menggunakan karakter backtick hardcoded, kita dapat mempertimbangkan untuk menggunakan supportsQuotedIdentifiers
dan getIdentifierQuoteString
metode java.sql.DatabaseMetaData
kelas.
(Pada kode OP, kita tidak melihat tipe data dari isi attributes
. Kami melihat panggilan ke metode bernama replace
, dan argumen yang diberikan untuk itu. Dengan asumsi bahwa attributes
adalah sebuah String, dan itu seharusnya menjadi nama kolom, sama sekali tidak jelas mengapa kita memiliki "spasi spasi tanda kutip tunggal" dalam string, atau mengapa kita perlu menghapusnya. Selain penyebutan ini, jawaban ini tidak membahas itu.)