Đúng. Chúng tôi không thể cung cấp số nhận dạng làm thông số liên kết. Tên của cột phải là một phần của văn bản SQL.
Chúng tôi có thể kết hợp động tên của cột vào văn bản SQL với một cái gì đó như sau:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
Và cung cấp giá trị cho hai tham số ràng buộc còn lại
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
Và bạn hoàn toàn đúng khi lo lắng về SQL Injection.
Được cung cấp dưới dạng giá trị ràng buộc, dấu ngoặc kép trong các giá trị của attrData
và medname
sẽ không phải là một vấn đề, về mặt SQL Injection.
Nhưng ví dụ tôi đã cung cấp là dễ bị tổn thương thông qua việc kết hợp colname
vào văn bản SQL, nếu chúng tôi không có một số đảm bảo rằng colname
là "an toàn" để đưa vào tuyên bố.
Vì vậy, chúng ta cần gán một giá trị cho colname
"an toàn".
Một số cách tiếp cận chúng ta có thể sử dụng để làm điều đó. Cách an toàn nhất sẽ là cách tiếp cận "danh sách trắng". Mã có thể đảm bảo rằng chỉ các giá trị "an toàn" được phép cụ thể mới được gán cho colname
, trước colname
được đưa vào văn bản SQL.
Ví dụ đơn giản:
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
}
Một cách tiếp cận linh hoạt hơn là đảm bảo rằng ký tự hình nền không xuất hiện trong colname
. Trong ví dụ, giá trị của colname
đang được trốn thoát bằng cách đặt nó trong dấu gạch ngược. Vì vậy, miễn là ký tự hình nền không xuất hiện trong colname
, chúng tôi sẽ ngăn không cho một giá trị đã cung cấp được hiểu là bất kỳ thứ gì khác ngoài giá trị nhận dạng.
Để có một cách tiếp cận chung chung hơn (và phức tạp hơn) để sử dụng các ký tự backtick được mã hóa cứng, chúng tôi có thể cân nhắc sử dụng supportsQuotedIdentifiers
và getIdentifierQuoteString
phương thức của java.sql.DatabaseMetaData
lớp.
(Trong mã OP, chúng tôi không thấy loại dữ liệu nội dung của các thuộc tính attributes
. Chúng tôi thấy một lệnh gọi đến một phương thức có tên là replace
và các đối số được cung cấp cho điều đó. Giả sử rằng các thuộc tính attributes
là một Chuỗi và đó được cho là một tên cột, hoàn toàn không rõ ràng tại sao chúng ta lại có "khoảng trắng dấu nháy đơn" trong chuỗi hoặc tại sao chúng ta cần loại bỏ điều đó. Ngoài đề cập này, câu trả lời này không giải quyết vấn đề đó.)