Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
#1

Правильно составить запрос, содержащий "'"

10.11.2014, 21:15. Просмотров 860. Ответов 20
Метки нет (Все метки)

Или такая запись/чтение в БД невозможна?
android.database.sqlite.SQLiteException: near "Этуаль":
syntax error (code 1): , while compiling: SELECT _id FROM providers WHERE name='Л'Этуаль'
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.11.2014, 21:15
Ответы с готовыми решениями:

Работа с БД, связывание таблиц "фильмы", "жанры", "режиссеры"
Ребят, всем привет! накидайте какие-нить идеи по реализации ситуация такая...

Ошибка "Unknown method "e" of "org.apache.commons.logging.Log"
Unknown method 'e' of 'org.apache.commons.logging.Log' package...

При копировании активити с другого проекта появляется запрос: "Что использовать?"
Создаю новый проект в андроид студио и добавил в него активити с другого...

Постепенно вывести на экран слово "Java", в котором буквы состоят из "интересных" элементов
Я учусь в универе и вот пытаюсь делать лабораторные по языку java, только на...

Выбор платформы разработки "1С Мобильная платформа" или "Android Studio"
Всем, здравствуйте! Есть задача по разработке клиента для терминала сбора...

20
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
11.11.2014, 09:37 #2
Rube, уважаемый, я недавно сам натолкнулся на такое. Рекомендую ознакомиться с некоторыми статьями на stackoverflow, если хотите, могу дать ссылки. Причём, select - это ещё не самый страшный вариант. Вот когда та же ерунда с insert и update - тут уже репу зачешешь.
Рекомендую использовать, например, метод rawQuery. Второй параметр - список значений. Надо проверить, обязательно ли писать new String[].
http://stackoverflow.com/questions/1...l-query-string
1
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
11.11.2014, 15:54  [ТС] #3
CoolMind, да я привык, еще с Access, запросы так писать, думаю можно конечно проверять критерии на "'" при записи и при чтении, но хотелось бы без проверки, как например в Regex - предварять наклонной чертой (\.*?+[{|()^$).
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 09:31 #4
Rube, да, согласен, но SQL использует стиль Паскаля при оформлении строк, а потому апострофы надо удваивать, впрочем, как и кавычки. Можно, конечно, таким способом попробовать. Ещё есть вариант с DatabaseUtils.sqlEscapeString(), но он, как минимум, добавляет апострофы в начале и в конце SQL-выражения.
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
12.11.2014, 10:57  [ТС] #5
Цитата Сообщение от CoolMind Посмотреть сообщение
а потому апострофы надо удваивать
Чтобы удваивать надо их находить, что равноценно моему сообщению ранее. Вобщем буду так и делать, находить их перед записью в БД и выкидывать.
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 11:19 #6
Я ранее столкнулся с апострофами в операциях insert, update, но сегодня решил, на всякий случай, проверить, как себя ведут select'ы. Оказалось, что если пользователь в поиске использует апострофы, то программа падает. Потому что использовал такую форму: T.title LIKE '%" + pattern + "%'".
Использовал вот такой вариант: T.title LIKE " + DatabaseUtils.sqlEscapeString("%" + pattern + "%"). Вроде, работает.

Добавлено через 10 минут
Цитата Сообщение от Rube Посмотреть сообщение
находить их перед записью в БД и выкидывать
Этот вариант не очень хорош. Мне досталась программа как раз с таким способом работы, я отказался от него, потому что так нечестно.
Нужно использовать более правильные способы работы с БД. Вот два примера. http://habrahabr.ru/post/190876/ и http://tech.vg.no/2011/04/04/speeding-up-sqlite-insert-operations/
Используя их, я добился как увеличения скорости, так и обхода проблемы с апострофами. Если будет желание, напишу статью.
Вот мой код.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            helper = new Helper(context);
            SQLiteDatabase db = helper.getWritableDatabase();
            db.beginTransaction();
 
            sqlUpdate = "UPDATE revision SET revision = ? WHERE city_id = ? AND name LIKE ?";
            stmtUpdate = db.compileStatement(sqlUpdate);
 
            stmtUpdate.bindLong(1, rev);
            stmtUpdate.bindLong(2, city_id);
            stmtUpdate.bindString(3, name);
            stmtUpdate.execute();
 
            db.setTransactionSuccessful();
            db.endTransaction();
Со строками там надо быть осторожным. Как всегда, мало где написано. Если строка = null, то надо написать такую процедуру:
Java
1
2
3
4
5
6
    private void bindString(SQLiteStatement stmt, int index, String value) {
        if (value == null)
            stmt.bindNull(index);
        else
            stmt.bindString(index, value);
    }
1
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
12.11.2014, 15:49  [ТС] #7
Вот что выяснил, запрос хорошо отрабатывает если помещать критерии в кавычки, WHERE name="Л'ЭтуальЭ".
Осталось выяснить как программно вставить эти кавычи.
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 16:00 #8
Rube, вы наткнётесь на грабли с кавычками. Их тоже надо уметь удваивать. Выше приводил пример с DatabaseUtils.sqlEscapeString(), мне кажется, должно работать так:
Java
1
2
String name = "Л'Этуаль";
String sql = "WHERE name = " +  DatabaseUtils.sqlEscapeString(s);
0
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
12.11.2014, 16:37 #9
Цитата Сообщение от Rube Посмотреть сообщение
Осталось выяснить как программно вставить эти кавычи.
Java
1
2
String name = "Л'Этуаль";
String query = "WHERE name = '" + name + "'";
Так не сработает разве?
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 16:54 #10
Spelcrawler, нет, будет указанная ошибка в первом сообщении ошибка.
0
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
12.11.2014, 16:55 #11
Тогда так)
Java
1
String query = "WHERE name = "" + name + """;
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 17:00 #12
Spelcrawler, это будет строка без переменной внутри.
2 варианта: либо вручную использовать замену апострофов на двойные апострофы, либо использовать sqlEscapeString.
0
androbro
343 / 303 / 68
Регистрация: 17.10.2014
Сообщений: 897
12.11.2014, 17:00 #13
А они бэкслэшем не экранируются
Java
1
String name = \'Этуаль";
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
12.11.2014, 17:07 #14
androbro, это не имеет смысла, потому что SQL не будет обращать внимания на "\'". Он будет обращать внимание, если распознает такое:
SQL
1
2
WHERE name = 'Л'Этуаль'
WHERE name = 'Л\'Этуаль'
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
13.11.2014, 09:04  [ТС] #15
Решил проблему неожиданно)
Java
1
2
String n = "=\"" + "Л'Этуаль" + "\"";       
"SELECT * FROM TABLE WHERE NAME " + n;
Но теперь проблема с текстом который содержит кавычки. Видимо придется все же проверять переменную на символы.

Добавлено через 10 часов 52 минуты
Java
1
2
3
public String replaceSingleQuote(String n) {    
    return "=" + (n.contains("'") ? "\"" + n + "\"" : "'" + n + "'");
}
0
dubok79
324 / 122 / 10
Регистрация: 01.11.2012
Сообщений: 586
14.11.2014, 08:38 #16
Вместо конкретного символа используйте его UNICODE представление. Например, для LIKE '%слово%' тоже ругался на знак процента. Написав его в unicode, все прошло как по маслу. Правда, если заранее не знаете какие символы, то нужно делать проверку и замену. Удачи.
1
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
14.11.2014, 13:43 #17
Я не понимаю, над чем до сих пор мучаетесь. Процент, конечно же, прекрасно работает в SQL-запросе, если запрос написан по правилам. Например, "WHERE LIKE '%%аб%'". Ещё есть вероятность получить SQL-инъекцию, но sqlEscapeString должна решать и этот вопрос.
1
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
14.11.2014, 13:53  [ТС] #18
Цитата Сообщение от CoolMind Посмотреть сообщение
Я не понимаю, над чем до сих пор мучаетесь.
Это dubok79 мучается, я же проблему давно решил двумя постами выше.
0
dubok79
324 / 122 / 10
Регистрация: 01.11.2012
Сообщений: 586
14.11.2014, 14:02 #19
Я не мучаюсь, а предложил свой вариант, который тоже работает. Почему так, потому что с MySQL постольку поскольку, а в нем видать есть методы мне не известные и похоже вам тоже.
0
CoolMind
421 / 404 / 65
Регистрация: 06.10.2012
Сообщений: 1,732
15.11.2014, 13:00 #20
dubok79, кстати, хорошо, что вы написали про процент. Проверил, действительно, процент не ищет, находит в итоге все записи. Я чего-то про такой вариант даже и не думал. Попробую ваш вариант.
0
15.11.2014, 13:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2014, 13:00

При эмулировании вместо надписи "Hello world" отображается "android"
Привет форумчане! Я только-только начинал программировать на андроиде. Поставил...

Как "превратить" string "6.971245e-001" во float?
Число конечно пример

Как прикрутить "свой браузер" к странице - "фрагмент"
здравствуйте. все, уже голову сломал. не соображаю совсем. не получается...


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

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

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