Я пытаюсь разобраться в этом два дня, но все ответы слишком сложные. Мне нужно простое и легкое решение, пожалуйста.
Я хочу создать функцию поиска книг с использованием HTML-форм и запросов POST к сервлету причала. Пользователь может выполнять поиск по названию книги, имени автора или по ценовому диапазону. В зависимости от ввода пользователя я сгенерирую SQL-запрос. Мой запрос выглядит так: -
(title, author и minPrice, maxPrice - переменные, вводимые пользователем.)
SELECT *
FROM books
WHERE Title LIKE '%title%'
OR Author LIKE '%author%'
OR Price BETWEEN minPrice AND maxPrice;
Если пользователь выставляет ценовой диапазон, все работает отлично. Но если они этого не сделают, запрос будет таким:
SELECT *
FROM books
WHERE Title LIKE '%%'
OR Author LIKE '%%'
OR Price BETWEEN AND;
и это ничего не возвращает.
Как лучше всего это сделать?
Код Java:
query = "SELECT *
FROM books
WHERE Title LIKE '%" + request.getParameter("title") + "%'
OR Author LIKE '%" + request.getParameter("author") + "%'
OR Price BETWEEN " + request.getParameter("minPrice") +
" AND " + request.getParameter("maxPrice") + ";";
Я предполагаю, что ваш запрос - это строка, которую вы используете в PreparedStatement. Если это так, вы можете просто создать свой запрос на основе необязательных параметров, которые вы получаете от внешнего интерфейса.
Код Java: String query = "SELECT * FROM books WHERE Title LIKE '%" + request.getParameter ("title") + "%' OR Author LIKE '%" + request.getParameter ("author") + "%' OR Цена МЕЖДУ "+ request.getParameter (" minPrice ") +" И "+ request.getParameter (" maxPrice ") +"; ";
Каш в следующий раз добавит этот код в вопрос.
Предупреждение о внедрении SQL-кода xkcd.com/327




Просто используйте для этого проверку, поэтому вы говорите в Коде, что диапазон цен не должен быть нулевым и / или 0, иначе показывать сообщение на экране и не добиться успеха. Есть также другие способы сделать это, чтобы ограничить отсутствие ввода, например, проверка PrimeFaces. Или вы просто определяете значения по умолчанию, если ввод равен нулю. Всего 3 тысячи решений. На будущее также предоставьте некоторую информацию о том, что вы используете и как выглядит ваш код, чтобы мы могли дать точный ответ на эту проблему.
SELECT *
FROM books
WHERE (Title LIKE '%title%' or title IS NULL)
OR (Author LIKE '%author%' or author IS NULL)
OR (Price BETWEEN minPrice AND maxPrice or minPrice IS NULL or maxPrice IS NULL);
Я не уверен, что это сработает из подготовленного Java-запроса (я также скептически отношусь к своему собственному ответу). Возможно, ОП может дать нам отзыв.
@TimBiegeleisen OP не использует подготовленный оператор :(
Вы были правы, говоря, что OP не использовал подготовленный оператор.
Похоже, что вы в настоящее время не используете подготовленный оператор. Лучше всего здесь иметь отдельные подготовленные операторы, которые вы используете, в зависимости от того, какие входы определены, а какие не определены.
Вы мог бы сможете обойтись одним оператором с помощью некоторой умной логики привязки заполнителя.
String title = request.getParameter("title");
String author = request.getParameter("author")
String minPriceStr = request.getParameter("minPrice");
Integer minPrice = minPriceStr != null ? Integer.parseInt(minPriceStr) : null;
String maxPriceStr = request.getParameter("maxPrice");
Integer maxPrice = maxPriceStr != null ? Integer.parseInt(maxPriceStr) : null;
String sql = "SELECT * FROM books WHERE Title LIKE ? OR Author LIKE ? OR ";
sql += "Price BETWEEN ? AND ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, title != null ? "%" + title + "%" : "%%");
ps.setString(2, author != null ? "%" + author + "%" : "%%");
ps.setInt(3, minPrice != null ? minPrice : -1);
ps.setInt(4, maxPrice != null ? maxPrice : 10000000);
ResultSet rs = ps.executeQuery();
// process result set
while (rs.next()) {
}
В этом ответе используется пара уловок. Во-первых, для названий или авторов null мы привязываем %% к выражениям LIKE. Это означало бы, что эти выражения всегда будут истинными и фактически их даже не будет. Для минимальной и максимальной цены мы проверяем, отсутствуют ли какие-либо из них, и в этом случае заменяем их на -1 и 10000000 соответственно. Это предполагает, что у вас никогда не будет цена меньше 0 или цена больше 10 миллионов.
Почему бы не назначать значения по умолчанию для minPrice и maxPrice при назначении?
Мы тоже могли бы это сделать. Я устал редактировать, и теперь буду ждать отзыва от ОП. Думаю, лучше всего здесь сделать отдельные заявления.
Я не знаю Java, но этот запрос sql будет работать
SELECT *
FROM books
WHERE Title LIKE '%title%'
OR Author LIKE '%author%'
OR (minPrice is null or maxPrice is null or Price BETWEEN minPrice AND maxPrice);
query =
"SELECT *
FROM books
WHERE Title LIKE '%" + request.getParameter("title") + "%'
OR Author LIKE '%" + request.getParameter("author") + "%'
OR (" + request.getParameter("minPrice") + " is null
or " + request.getParameter("maxPrice") + " is null
or
Price BETWEEN " + request.getParameter("minPrice") +
" AND " + request.getParameter("maxPrice") + ");";
Вы должны использовать подготовленный оператор, и я сомневаюсь, что он сработает, особенно если параметры могут быть null.
Вам действительно стоит показать нам свой Java-код. Без этого ваш вопрос немного неограничен.