Форум программистов, компьютерный форум, киберфорум
Наши страницы

Java и базы данных

Войти
Регистрация
Восстановить пароль
 
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
#1

Как правильно экранировать одиночную кавычку для MySQL на Java? - Java БД

24.11.2016, 12:09. Просмотров 690. Ответов 10
Метки нет (Все метки)

Добрый день, уважаемые коллеги

Подскажите, пожалуйста, как быть? Сегодня утром обнаружил пренеприятнейший баг в моем проекте.
При вводе пользователем одиночной кавычки '
в любое текстовое поле формы и последующей попытки записать через JDBC sql-запрос в MySQL базу вылетает "SQL syntax exception". Необходимо экранировать одиночную кавычку, что бы исправить это дело.
Явно подобная проблема уже решалась неоднократно ранее? Есть ли в Java какой то метод экранирования для MySQL?

Или создать в ручную класс, а в нем метод:
Java
1
2
3
4
5
6
7
8
9
10
11
12
 // Замена символов ' и ' на соответственно  ' и  '
    private String replaceEscChars (String source) {
        StringBuffer sb = new StringBuffer ();
        for (int i = 0; i < source.length (); i++) {
            switch (source.charAt (i)) {
                case ' '': sb.append ('\ ''); break;
                case ' '': sb.append ('\ ''); break;
                default  : sb.append (source.charAt (i));
            }
        }
        return sb.toString ();
    }
И по каждому полю проводить проверку? Или наверное уже в контроллере проводить проверку...
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.11.2016, 12:09
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как правильно экранировать одиночную кавычку для MySQL на Java? (Java БД):

Как правильно соединить Java и MySQL? - Java БД
Помогите ПЛИЗ. Надо соединится с базой MySQL. Как это сделать? Сначала слышал надо зарегистрировать драйвер. Я его скачал. Потом прописал...

Как в строку написать одиночную кавычку - PascalABC.NET
Вот к вам небольшая задача, дорогие друзья! Как в строку написать одиночную кавычку. Нужна именно одиночная! Вот так выдает ошибку: ...

Как удалить одиночную кавычку в начале текста в каждой ячейке документа? - MS Excel
Большинство ячеек таблицы были заполнены знаками + или -. Но excel не даёт их просто так ставить, считает за формулы строки, начинающиеся с...

.NET 4.x Не могу экранировать символы для Mysql - C#
Здравствуйте. Интересует вопрос, как заэкранировать все ненужные символы для добавления строки в Mysql. Например открываю страницу,...

Как экранировать слеш для char? - C++
Привет всем.. Подскажите как сравнить значение char со слешем? Вот так не работает( char *buf = new char ; if (buf == '\') ...

Как правильно сделать запрос к MySQL для подсчета записей - PHP БД
Всем привет. Сделал себе вот такой вывод всех категорий на главной странице сайта (CMS DLE): ссылка удалена Выводится: название и...

10
LeX
301 / 301 / 81
Регистрация: 30.06.2010
Сообщений: 1,171
24.11.2016, 13:39 #2
как ты запрос формируешь?
1
turbanoff
Модератор
Эксперт Java
3981 / 3716 / 462
Регистрация: 18.05.2010
Сообщений: 9,291
Записей в блоге: 11
Завершенные тесты: 1
27.11.2016, 17:06 #3
Для вставки данных пользователя в базу нужно использовать PreparedStatement. Это позволит отделить текст SQL от данных - и тогда не нужно будет ничего экранировать.
https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Добавлено через 27 секунд
Примеры есть вот тут - JDBC FAQ для начинающих
1
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
28.11.2016, 14:19  [ТС] #4
turbanoff, дак так и делаю, через PreparedStatement. Там Swing форма, JTextFeild и JTextArea, после заполнения пользователем, стандартно
MySQL
1
INSERT INTO table_name ... WHERE id = ' '
На работе буду в конце недели, перепроверю. Точно не помню, как там сделано. Но все работает идеально. Возникает проблема если в JTextArea вставить ', потому как данные собираются из нескольких полей формы и выполняется конкатенация, а когда доходит до символа ', statement думает что это конец вставляемой строки...
Спасибо всем. Я все же перепроверю, как на работе буду...
0
turbanoff
Модератор
Эксперт Java
3981 / 3716 / 462
Регистрация: 18.05.2010
Сообщений: 9,291
Записей в блоге: 11
Завершенные тесты: 1
28.11.2016, 17:30 #5
TurboDuck, конкатенации быть не должно.
Текст запроса должен выглядеть как-то так:
SQL
1
INSERT INTO TABLE_NAME ... WHERE id = ?
А значение для ? уже должно задаваться с помощью методов set* у PreparedStatement
Например с помощью setInt
1
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
28.11.2016, 18:08  [ТС] #6
turbanoff, а вот это я как раз упустил! Спасибо!!
0
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
06.12.2016, 08:55  [ТС] #7
turbanoff, а все равно не получится так. При апдейте критует, как записать строку "it's" в MySQL?

Java
1
2
3
4
5
6
7
8
String javaString = "It's a beautiful day";
String sql = "UPDATE table_name SET Column_Name = '"+javaString+"'";
 
try {
con = DriverManager.getConnection(conString, username, password);
s = con.prepareStatement(sql);
s.execute(sql);
{ catch .... и т.д.
И получаем:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax

javaString название переменной и ее содержимое просто для примера, строку получаем методом getText() из JTextField, может там как то парсить? Проверить текст и заменить символ на /' или так в Java не работает?

Добавлено через 7 минут
Не могли бы Вы поподробнее объяснить, как при помощи PreparedStatement обработать строку полученную методов getText() из поля JTextField?

Добавлено через 10 минут
Вариант такой нашел.. в принципе велосипед и наверное даже поедет.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    public static String forJSON(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        int len = input.length();
        // сделаем небольшой запас, чтобы не выделять память потом
        final StringBuilder result = new StringBuilder(len + len / 4);
        final StringCharacterIterator iterator = new StringCharacterIterator(input);
        char ch = iterator.current();
        while (ch != CharacterIterator.DONE) {
            if (ch == '\n') {
                result.append("\\n");
            } else if (ch == '\r') {
                result.append("\\r");
            } else if (ch == '\'') {
                result.append("\\\'");
            } else if (ch == '"') {
                result.append("\"");
            } else {
                result.append(ch);
            }
            ch = iterator.next();
        }
        return result.toString();
    }
Все таки интересно, как через PreparedStatement реализуется?
0
turbanoff
Модератор
Эксперт Java
3981 / 3716 / 462
Регистрация: 18.05.2010
Сообщений: 9,291
Записей в блоге: 11
Завершенные тесты: 1
06.12.2016, 13:51 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Надо так:
Java
1
2
3
4
5
String sql = "UPDATE table_name SET Column_Name = ?";
//...
PreparedStatement s = con.prepareStatement(sql);
s.setString(1, javaString);
s.execute();
1
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
06.12.2016, 16:13  [ТС] #9
turbanoff, спасибо! А то не меня ни как не покидало чувство, что я изобретаю велосипед.

Добавлено через 1 час 39 минут
turbanoff, не могу понять где ошибка, сделал все как у Вас. Вылетает с исключением:
java.sql.SQLException: Parameter index out of range (1 > number of parametres, which is 0).

В импорте:
import java.sql.PreparedStatement;

Ниже по исключению:
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3321)

первая ссылка на код программы имено на строку:
Java
1
s.setString(1, javaString);
Похоже компилируется с методом PreparedStatement из другого пакета что ли?

Добавлено через 28 минут
Все разобрался! Мой косяк =)

Оставаясь подклассом класса Statement, класс PreparedStatement наследует все функции от Statement. Методы - execute, executeQuery и executeUpdate - модифицированы таким образом, что не имеют аргументов. Старые методы класса Statement (которые принимают SQL-выражения в качестве едиственного аргумента) не должны использоваться в объекте PreparedStatement.
0
turbanoff
Модератор
Эксперт Java
3981 / 3716 / 462
Регистрация: 18.05.2010
Сообщений: 9,291
Записей в блоге: 11
Завершенные тесты: 1
06.12.2016, 16:13 #10
TurboDuck, если так ругается, значит не хватает вопросиков в вашем тексте запроса.
0
TurboDuck
41 / 41 / 11
Регистрация: 23.11.2015
Сообщений: 368
07.12.2016, 07:02  [ТС] #11
turbanoff, проблема была в том, что я передавал параметр (sql запрос) в метод execute(), а в PreparedStatement, в отличие от Statement этот метод переопределен и не принимает параметры. Без параметров, все заработало.
0
07.12.2016, 07:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.12.2016, 07:02
Привет! Вот еще темы с ответами:

Как правильно настроить параметры MYSQL для большого числа запросов? - MySQL
Как правильно настроить параметры MYSQL для большого числа запросов?

Как экранировать кавычки и другие опасные символы для записи в БД - C++
В переменной типа(класса) string иногда бывают кавычки типо &quot; или ' как можно быстро проверить содержание переменной и как то...

драйвер java для MySQL - MySQL
Друг, :)) ты же сам на свой вопрос ответил, создаёшь переменную CLASSPATH, и добавляешь туда путь с названием файла...

Как вставить кавычку в строку - C#
Как так что бы знак опострова &quot;&quot; в виде текста видел в определенных местах???


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.