Использование подстановочного знака «как» в подготовленном утверждении

176

Я использую подготовленные операторы для выполнения запросов к базе данных MySQL. И я хочу реализовать функцию поиска на основе своего рода ключевого слова.

Для этого мне нужно использовать LIKEключевое слово, это я много знаю. И я также использовал подготовленные заявления раньше, но я не знаю , как использовать его с , LIKEпотому что из следующего кода , где бы я добавить 'keyword%'?

Могу ли я напрямую использовать его pstmt.setString(1, notes)как (1, notes+"%")или что-то подобное. Я вижу много сообщений на эту тему в Интернете, но нигде нет хорошего ответа.

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();
ПЛА
источник

Ответы:

281

Вам нужно установить его в самом значении, а не в подготовленной строке SQL оператора.

Итак, это должно быть сделано для соответствия префикса:

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

или суффикс-совпадение:

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

или глобальное совпадение:

pstmt.setString(1, "%" + notes + "%");
BalusC
источник
18
+1 ОП может «установить» его в SQL - как, например, ... LIKE '%' || ? || '%'или аналогично - но это гораздо менее гибко.
знак абзаца
Как я могу сделать это в режиме НЕКЕЙС ЧУВСТВИТЕЛЬНЫЙ? :)
Альфа Габриэль В. Тимбол
2
Нечувствительный к регистру можно по-прежнему использовать WHERE UPPER(?) LIKE UPPER(?)при использованииpstmt.setString(2, "%" + notes + "%")
Zig
1
@Alain: Спасибо. Просто интересно, относится ли это ко всем РСУБД, о которых знает мир? Возможно, '%' || ? || '%'как уже упоминалось в 1-м комментарии, все-таки лучше? У меня нет возможности экспериментировать прямо сейчас.
BalusC
2
@BalusC это относится к MSSQL, Postgres и MySQL в моем тестировании. Строка, превращаемая в параметр, сама по себе интерпретируется как набор данных и команд управления. Конкатенация SQL происходит до ее интерпретации и сохраняет уязвимость. Центр безопасного проектирования IEEE говорит о строгом разделении данных и инструкций по управлению, а не инструкций по управлению процессами, полученных из ненадежных источников .
Ален О'Ди
28

Код это так:

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

Убедитесь, что вы НЕ включаете кавычки, как показано ниже, поскольку они вызовут исключение.

pstmt.setString(1,"'%"+ notes + "%'");
Свадебный Волк
источник
1
Хотя это звучит так, будто кто-то не столкнется с этим предположением, на самом деле это очень верно, особенно при работе с Oracle. Спасибо за указание!
спрашивает
5

мы можем упростить это, используя функцию CONCATE SQL.

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

это идеально подходит для моего случая.

Башарат Али
источник
4
PreparedStatement ps = cn.prepareStatement("Select * from Users where User_FirstName LIKE ?");
ps.setString(1, name + '%');

Попробуйте это.

Файз
источник
1
String fname = "Sam\u0025";

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

ps.setString(1, fname);
Рам Кумар
источник
2
Не могли бы вы разработать ответ, а не просто дать ответ? Смотрите: stackoverflow.com/help/how-to-answer
Эдвин
-13
String query="select * from test1 where "+selected+" like '%"+SelectedStr+"%';";


PreparedStatement preparedStatement=con.prepareStatement(query);


// where seleced and SelectedStr are String Variables in my program
Махеш Дхоте
источник
небезопасно, любезно используйте параметризованное подготовленное заявление.
Дургеш Кумар