Sử dụng thẻ giống như wildcard trong tuyên bố đã chuẩn bị


176

Tôi đang sử dụng các câu lệnh được chuẩn bị để thực hiện các truy vấn cơ sở dữ liệu mysql. Và tôi muốn thực hiện chức năng tìm kiếm dựa trên một từ khóa sắp xếp.

Cho rằng tôi cần phải sử dụng LIKEtừ khóa, nhiều đến mức tôi biết. Và tôi cũng đã sử dụng các câu lệnh được chuẩn bị trước đó, nhưng tôi không biết làm thế nào để sử dụng nó LIKEbởi vì từ đoạn mã sau tôi sẽ thêm vào 'keyword%'đâu?

Tôi có thể trực tiếp sử dụng nó pstmt.setString(1, notes)như là (1, notes+"%")hoặc một cái gì đó như thế. Tôi thấy rất nhiều bài viết về điều này trên web nhưng không có câu trả lời tốt ở bất cứ đâu.

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();

Câu trả lời:


281

Bạn cần đặt nó trong chính giá trị, không phải trong chuỗi SQL câu lệnh đã chuẩn bị.

Vì vậy, điều này nên làm cho một trận đấu tiền tố:

notes = notes
    .replace("!", "!!")
    .replace("%", "!%")
    .replace("_", "!_")
    .replace("[", "![");
PreparedStatement pstmt = con.prepareStatement(
        "SELECT * FROM analysis WHERE notes LIKE ? ESCAPE '!'");
pstmt.setString(1, notes + "%");

hoặc một trận đấu hậu tố:

pstmt.setString(1, "%" + notes);

hoặc một trận đấu toàn cầu:

pstmt.setString(1, "%" + notes + "%");

18
+1 OP có thể "thiết lập" nó trong SQL - bằng ... LIKE '%' || ? || '%'hoặc tương tự - nhưng nó kém linh hoạt hơn nhiều.
hương

Làm thế nào để tôi làm điều đó với chế độ SENSITIVE NON-CASE? :)
Alpha Gabriel V. Timbol

2
Không phân biệt chữ hoa chữ thường vẫn có thể sử dụng WHERE UPPER(?) LIKE UPPER(?)khi sử dụngpstmt.setString(2, "%" + notes + "%")
Zig

1
@ Alain: Cảm ơn bạn. Chỉ cần tự hỏi, điều này có áp dụng cho tất cả RDBMS mà thế giới biết không? Có lẽ '%' || ? || '%'như được đề cập trong bình luận 1 đã tốt hơn, sau tất cả? Tôi không có cơ hội thử nghiệm ngay bây giờ.
BalusC

2
@BalusC điều này áp dụng cho MSSQL, Postgres và MySQL trong thử nghiệm của tôi. Chuỗi được tạo thành một tham số tự nó được hiểu là sự pha trộn của dữ liệu và hướng dẫn điều khiển. Kết nối SQL xảy ra trước khi nó được giải thích và bảo tồn lỗ hổng. Trung tâm thiết kế an toàn của IEEE nói với các hướng dẫn kiểm soát và dữ liệu riêng biệt nghiêm ngặt và không bao giờ các hướng dẫn kiểm soát quy trình nhận được từ các nguồn không đáng tin cậy .
Alain O'Dea

28

Mã nó như thế này:

PreparedStatement pstmt = con.prepareStatement(
    "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes + "%");`

Đảm bảo rằng bạn KHÔNG bao gồm các trích dẫn '' như bên dưới vì chúng sẽ gây ra ngoại lệ.

pstmt.setString(1,"'%"+ notes + "%'");

1
Mặc dù nghe có vẻ như ai đó sẽ không gặp phải giả định này, nhưng nó thực sự rất hợp lệ, đặc biệt là khi làm việc với Oracle. Cảm ơn đã chỉ ra!
vào

5

chúng ta có thể đơn giản làm điều này bằng cách sử dụng hàm SQL CONCATE.

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like CONCAT( '%',?,'%')";
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();

đây là công việc hoàn hảo cho trường hợp của tôi


4
PreparedStatement ps = cn.prepareStatement("Select * from Users where User_FirstName LIKE ?");
ps.setString(1, name + '%');

Thử thứ này đi.


1
String fname = "Sam\u0025";

PreparedStatement ps= conn.prepareStatement("SELECT * FROM Users WHERE User_FirstName LIKE ? ");

ps.setString(1, fname);

2
Bạn có thể giải thích câu trả lời thay vì chỉ đưa ra câu trả lời? Xem: stackoverflow.com/help/how-to-answer
Edwin

-12
String query="select * from test1 where "+selected+" like '%"+SelectedStr+"%';";


PreparedStatement preparedStatement=con.prepareStatement(query);


// where seleced and SelectedStr are String Variables in my program

Nó không an toàn, vui lòng sử dụng chuẩn bị tham số.
Durgesh Kumar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.