2010-05-26 39 views
10

Tôi đang cố gắng sử dụng một PreparedStatement với mã tương tự như sau:PreparedStatement.setString() mà không có dấu ngoặc kép

SELECT * FROM ? WHERE name = ? 

Rõ ràng, những gì xảy ra khi tôi sử dụng setString() để thiết lập các bảng và tên trường là này:

SELECT * FROM 'my_table' WHERE name = 'whatever' 

và truy vấn không hoạt động. Có cách nào để thiết lập các chuỗi mà không có dấu ngoặc kép vì vậy các dòng trông như thế này:

SELECT * FROM my_table WHERE name = 'whatever' 

hay nên tôi chỉ cung cấp cho nó lên và sử dụng Báo cáo thường xuyên thay vì (các đối số đến từ một phần khác của hệ thống, không ai trong số những người được nhập bởi người dùng)?

+0

Thực tế là bạn đang dự tính làm điều này gợi ý với tôi rằng bạn nên xem xét tu sửa dữ liệu của bạn. Có lẽ bạn nên tạo một khung nhìn phối hợp tất cả các bảng, với cột được thêm là 'tên bảng'. – nsayer

Trả lời

15

Không thể sử dụng tham số để tham số hóa bảng hoặc tham số hóa bất kỳ đối tượng cơ sở dữ liệu nào. Chúng được sử dụng chủ yếu cho tham số WHERE/HAVING.

Để thực hiện những gì bạn muốn, bạn sẽ cần tự mình thực hiện và tạo câu lệnh thông thường khi cần.

Khi bạn sử dụng câu lệnh đã chuẩn bị, đây là gợi ý cho cơ sở dữ liệu thực hiện xử lý trước trên bảng sao kê - ví dụ: phân tích chuỗi và có thể xác định kế hoạch thực hiện. Nếu các đối tượng được sử dụng trong truy vấn có thể thay đổi động, thì cơ sở dữ liệu không thể làm nhiều việc chuẩn bị trước.

+0

Để tiếp tục điều này, nó không phải là bằng cách sử dụng setString đặt dấu ngoặc kép xung quanh các chuỗi, bởi vì nó không (các biến ràng buộc không hoạt động theo cách đó). Nó chỉ là bạn không thể sử dụng một biến cho phần đó của truy vấn. – Donnie

+0

OK, cảm ơn! Bạn có thể nói bằng cách sử dụng PreparedStatement dosn't có ý nghĩa nhiều ở đây, cho paramenters không phải là người dùng nhập vào? Tôi có nghĩa là nó có thể tốn kém hơn so với sử dụng tuyên bố thường xuyên. Hoặc tôi có nên sử dụng PreparedStatement ở khắp mọi nơi không có vấn đề gì? – Slavko

+1

Bạn vẫn có thể sử dụng PreparedStatement, chỉ cần không cố gắng tham số hóa tên bảng - tham số hóa 'bất cứ ai'. Có một số cuộc tranh luận về việc sử dụng các báo cáo chuẩn bị so với thông thường, nhưng tôi tin rằng sự đồng thuận là sử dụng các báo cáo được chuẩn bị trừ khi bạn phát hiện ra các lý do chính đáng không. – mdma

2

Rất tiếc, bạn không thể tham số hóa tên bảng cho các câu lệnh đã chuẩn bị. Nếu muốn, bạn có thể xây dựng một String và thực hiện nó như là SQL động.

3

Tôi nghi ngờ rằng SQL của bạn thực sự linh hoạt theo cách đó. Bạn chỉ có một số lượng hữu hạn các bảng, vì vậy số lượng các chuỗi cuối cùng tĩnh để thể hiện SQL bạn cần là hữu hạn.

Tiếp tục sử dụng PreparedStatement và ràng buộc các biến của bạn. Nó hoàn toàn đáng giá, đặc biệt hữu ích khi tránh các vấn đề về SQL injection.

+0

Bạn rõ ràng không đọc đủ TheDailywtf.com. Có một bảng cho mỗi khách hàng (Và số lượng khách hàng không bị ràng buộc) là một mô hình chống sử dụng. –

+0

Rõ ràng là không. Cảm ơn cho những người đứng đầu lên. số 8) – duffymo

2

Sai lầm bạn đã làm là bạn không thể chuyển tên bảng làm thông số. Bạn chỉ nên chuyển các giá trị cho một câu lệnh SQL.

Ex: Nếu bạn wantto:

Select * from LoggedUsers where username='whatever' and privilege='whatever'; 

sau đó bạn đã xây dựng PreparedStatement như:

Select * from LoggedUsers where username=? and privilege=? 

setString(1, usernameObject); 
setString(2, privilegeObject); 

Mục đích của PreparedStatement là để giảm bớt khó khăn và khả năng đọc của mã kết nối cơ sở dữ liệu. khi nhà phát triển phải sử dụng quá nhiều giá trị cột với cá thể của Statement thì rất khó để đặt dấu chấm phẩy, dấu phẩy và dấu cộng (toán tử concat).

Tôi nghĩ bạn đang nhầm muốn tận dụng lợi thế của nó, mà không được thiết kế để ....

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