Các tham số truy vấn câu lệnh đúng, được chuẩn bị chỉ có thể được sử dụng ở nơi bạn sẽ sử dụng một giá trị bằng giá trị đơn. Bạn không thể sử dụng tham số cho tên bảng, tên cột, danh sách giá trị hoặc bất kỳ cú pháp SQL nào khác.
Vì vậy, bạn phải nội suy biến ứng dụng của bạn thành chuỗi SQL và trích dẫn chuỗi thích hợp. Đừng sử dụng trích dẫn để phân định tên bảng của bạn, và thoát khỏi chuỗi trích dẫn bằng cách nhân đôi nó:
java.sql.DatabaseMetaData md = conn.getMetaData();
String q = md.getIdentifierQuoteString();
String sql = "SELECT MAX(AGE) FROM %s%s%s";
sql = String.format(sql, q, tablename.replaceAll(q, q+q), q);
Ví dụ, nếu tên bảng của bạn là theo nghĩa đen table"name
, và RDBMS nhân vật nhận dạng báo giá của bạn là "
, sau đó sql
nên chứa một chuỗi như:
SELECT MAX(AGE) FROM "table""name"
tôi cũng đồng ý với bình luận @ ChssPly76 - đó là tốt nhất nếu người dùng nhập vào của bạn là thực sự không phải là tên bảng đen, nhưng một signifier rằng mã của bạn bản đồ vào một tên bảng, mà bạn sau đó liên polate vào truy vấn SQL. Điều này mang lại cho bạn nhiều sự đảm bảo hơn rằng không có sự tiêm SQL nào có thể xảy ra.
HashMap h = new HashMap<String,String>();
/* user-friendly table name maps to actual, ugly table name */
h.put("accounts", "tbl_accounts123");
userTablename = ... /* user input */
if (h.containsKey(userTablename)) {
tablename = h.get(userTablename);
} else {
throw ... /* Exception that user input is invalid */
}
String sql = "SELECT MAX(AGE) FROM %s";
/* we know the table names are safe because we wrote them */
sql = String.format(sql, tablename);
Nguồn
2009-11-05 00:28:14
Nếu tên bảng đến ** trực tiếp ** từ người dùng nhập vào, bạn đã có vấn đề lớn hơn nhiều lo lắng về vệ sinh hơn SQL của bạn (và nếu nó không có gì để khử trùng là) – ChssPly76