SQL игнорирует нулевой ввод пользователя в предложениях WHERE

userInput

Я пытаюсь разобраться в этом два дня, но все ответы слишком сложные. Мне нужно простое и легкое решение, пожалуйста.

Я хочу создать функцию поиска книг с использованием 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") + ";"; 

Вам действительно стоит показать нам свой Java-код. Без этого ваш вопрос немного неограничен.

Tim Biegeleisen 27.11.2018 14:45

Я предполагаю, что ваш запрос - это строка, которую вы используете в PreparedStatement. Если это так, вы можете просто создать свой запрос на основе необязательных параметров, которые вы получаете от внешнего интерфейса.

Stijn Van Bever 27.11.2018 14:45

Код 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 ") +"; ";

Kashif999 27.11.2018 14:49

Каш в следующий раз добавит этот код в вопрос.

Juan Carlos Oropeza 27.11.2018 14:55

Предупреждение о внедрении SQL-кода xkcd.com/327

Juan Carlos Oropeza 27.11.2018 14:57
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
113
4

Ответы 4

Просто используйте для этого проверку, поэтому вы говорите в Коде, что диапазон цен не должен быть нулевым и / или 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-запроса (я также скептически отношусь к своему собственному ответу). Возможно, ОП может дать нам отзыв.

Tim Biegeleisen 27.11.2018 14:50

@TimBiegeleisen OP не использует подготовленный оператор :(

Juan Carlos Oropeza 27.11.2018 14:52

Вы были правы, говоря, что OP не использовал подготовленный оператор.

Tim Biegeleisen 27.11.2018 15:08

Похоже, что вы в настоящее время не используете подготовленный оператор. Лучше всего здесь иметь отдельные подготовленные операторы, которые вы используете, в зависимости от того, какие входы определены, а какие не определены.

Вы мог бы сможете обойтись одним оператором с помощью некоторой умной логики привязки заполнителя.

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 при назначении?

Juan Carlos Oropeza 27.11.2018 15:12

Мы тоже могли бы это сделать. Я устал редактировать, и теперь буду ждать отзыва от ОП. Думаю, лучше всего здесь сделать отдельные заявления.

Tim Biegeleisen 27.11.2018 15:13

Я не знаю 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.

Tim Biegeleisen 27.11.2018 15:08

Другие вопросы по теме