2012-07-03 36 views
27

Tôi đang sử dụng đối tượng PreparedStatment java để xây dựng một loạt truy vấn INSERT theo đợt. Báo cáo kết quả truy vấn là các định dạng ...Cách sử dụng biến tablename cho câu lệnh chuẩn bị java chèn

String strQuery = "INSERT INTO ? (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 

... vì vậy cả hai giá trị trường và tablename là các biến (ví dụ. Tôi có nhiều bảng với định dạng cùng một cột trong đó mỗi chèn sẽ được dẫn đến một cái khác). Tôi có thể thực hiện các hoạt động nếu tôi xóa "?" tablename biến và mã cứng nhưng mỗi câu lệnh chuẩn bị sẽ được chèn vào một bảng khác nhau nên cần phải duy trì một biến tôi cư ngay trước khi thực hiện truy vấn hàng loạt sử dụng ...

stmt.setString(1, "tableName1"); 

Làm thế nào tôi có thể để điều này trở thành một động biến xin vui lòng?

Trả lời

37

Bạn không thể. Bạn cần phải đối chiếu sql với chuỗi nối/giữ chỗ với String.format. câu lệnh chuẩn bị là cho các giá trị cột không cho tên bảng.

+2

Cảm ơn mọi người ... có vẻ như tôi không biết tablename tôi muốn chèn vào cho đến khi trao đổi các biến cho mỗi hàng, điều tốt nhất là xây dựng chèn trong một thủ tục lưu sẵn DB. Sau đó chuyển tất cả các tham số cho mỗi hàng vào trong proc được lưu trữ, sau đó để cho DB xử lý thao tác tablename. Cảm ơn anyway folks cho các phản ứng mặc dù. :-) – ForestSDMC

+13

Điều này có nghĩa là bảo vệ chống tiêm SQL là không thể với các tên bảng động? –

+0

@Richard Tôi đã đi đến cùng một kết luận và nó có vẻ ngớ ngẩn, nhưng ít nhất nó là khá dễ dàng để kiểm tra tên bảng chống lại danh sách các bảng có sẵn trong cơ sở dữ liệu. – JulienD

-3

Bạn sẽ cần phải thêm nó vào chuỗi gốc:

String tableName = "some_table_name"; 
// some other code 
String strQuery = "INSERT INTO " + tableName + " (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 

Bạn có cần các dấu chấm phẩy trong strQuery? (bạn có thể làm, nó trông hơi lạ với tôi :-))

+6

dễ bị tổn thương đến SQL injection. KHÔNG SỬ DỤNG TRẢ LỜI NÀY, KIDS! – SigmaX

+6

... cũng phụ thuộc vào nơi tên bảng của bạn đến từ đâu. Nếu nó đến từ một người dùng hoặc từ một khách hàng không đáng tin cậy, thì tôi đồng ý với bạn. Nhưng nếu nó được chứa trong phương pháp của riêng bạn, thì sự bất biến của String có nghĩa là nó chắc chắn an toàn. –

+0

Về mặt kỹ thuật đúng. Nhưng câu trả lời hay vẫn cần một tuyên bố từ chối trách nhiệm lớn: "như một quy tắc, tránh sử dụng các truy vấn SQL động, thời gian — nó được coi là hành vi không an toàn. Nếu bạn phải làm điều này, hãy đảm bảo bạn biết chính xác những gì bạn đang làm". – SigmaX

-2

Không thể sử dụng tên bảng làm tham số. Nó phải được mã hóa cứng. Hãy thử một cái gì đó như:

String tableName = "tableName1"; 
String strQuery = "INSERT INTO " + tableName + " (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 
+7

Dễ bị tấn công SQL injection. KHÔNG SỬ DỤNG TRẢ LỜI NÀY, KIDS! – SigmaX

-1

Một thay thế có thể String.format:

ví dụ

String sql = String.format("INSERT INTO $1%s (col1, col2, col3, (etc)", myTablename); 
+15

Dễ bị SQL injection.KHÔNG SỬ DỤNG TRẢ LỜI NÀY, KIDS! – SigmaX

+12

Đây là thông thường "tôi biết SQL injection là gì" hoang tưởng - nó hoàn toàn phụ thuộc vào nơi myTablename xuất phát từ đó. – davidfrancis

+3

Đồng ý. Tuy nhiên, giống như hầu hết các vấn đề bảo mật, một phần lớn khách truy cập vào các trang web Hỏi & Đáp sẽ không hiểu rằng họ cần phải chú ý đến nơi mà myTablename xuất phát từ đó. Vì vậy, câu trả lời cần phải đủ điều kiện. – SigmaX

11

Bạn có thể sử dụng trình giữ chỗ thay cho tên bảng và sau đó thay thế bằng tên tablename của bạn.

String strQuery = "INSERT INTO $tableName (col1, col2, col3, col4, col5) 
        VALUES (?,?,?,?,?,?);"; 

và thay thế khi u đến để nhận biết tablename

String query =strQuery.replace("$tableName",tableName); 
stmt =conn.prepareStatement(query); 
+27

Dễ bị tấn công SQL. KHÔNG SỬ DỤNG TRẢ LỜI NÀY, KIDS! – SigmaX

+7

chỉ khi $ tablename được lấy từ đầu vào của người dùng, đúng không? Nhưng nó sẽ là tốt nếu một cái gì đó giống như một lựa chọn nút radio đã trở về một giá trị điều tra, hoặc bất kỳ phương pháp khác mà hạn chế các giá trị có thể có của $ tablename đến một bộ được xác định? – Toadfish

+9

@ SigmaX vì vậy giải pháp của bạn không dễ bị tấn công SQL injection là gì? – Mahdi

Các vấn đề liên quan