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

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

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

Или такая запись/чтение в БД невозможна?
android.database.sqlite.SQLiteException: near "Этуаль":
syntax error (code 1): , while compiling: SELECT _id FROM providers WHERE name='Л'Этуаль'
1
QA
Эксперт
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 com.mycompany.myapp; import...

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

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

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

20
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
11.11.2014, 09:37 2
Rube, уважаемый, я недавно сам натолкнулся на такое. Рекомендую ознакомиться с некоторыми статьями на stackoverflow, если хотите, могу дать ссылки. Причём, select - это ещё не самый страшный вариант. Вот когда та же ерунда с insert и update - тут уже репу зачешешь.
Рекомендую использовать, например, метод rawQuery. Второй параметр - список значений. Надо проверить, обязательно ли писать new String[].
http://stackoverflow.com/questions/1...l-query-string
1
Rube
912 / 560 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
11.11.2014, 15:54  [ТС] 3
CoolMind, да я привык, еще с Access, запросы так писать, думаю можно конечно проверять критерии на "'" при записи и при чтении, но хотелось бы без проверки, как например в Regex - предварять наклонной чертой (\.*?+[{|()^$).
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
12.11.2014, 09:31 4
Rube, да, согласен, но SQL использует стиль Паскаля при оформлении строк, а потому апострофы надо удваивать, впрочем, как и кавычки. Можно, конечно, таким способом попробовать. Ещё есть вариант с DatabaseUtils.sqlEscapeString(), но он, как минимум, добавляет апострофы в начале и в конце SQL-выражения.
0
12.11.2014, 09:31
Rube
912 / 560 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
12.11.2014, 10:57  [ТС] 5
Цитата Сообщение от CoolMind Посмотреть сообщение
а потому апострофы надо удваивать
Чтобы удваивать надо их находить, что равноценно моему сообщению ранее. Вобщем буду так и делать, находить их перед записью в БД и выкидывать.
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
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
912 / 560 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
12.11.2014, 15:49  [ТС] 7
Вот что выяснил, запрос хорошо отрабатывает если помещать критерии в кавычки, WHERE name="Л'ЭтуальЭ".
Осталось выяснить как программно вставить эти кавычи.
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
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,667
Завершенные тесты: 1
12.11.2014, 16:37 9
Цитата Сообщение от Rube Посмотреть сообщение
Осталось выяснить как программно вставить эти кавычи.
Java
1
2
String name = "Л'Этуаль";
String query = "WHERE name = '" + name + "'";
Так не сработает разве?
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
12.11.2014, 16:54 10
Spelcrawler, нет, будет указанная ошибка в первом сообщении ошибка.
0
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,667
Завершенные тесты: 1
12.11.2014, 16:55 11
Тогда так)
Java
1
String query = "WHERE name = "" + name + """;
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
12.11.2014, 17:00 12
Spelcrawler, это будет строка без переменной внутри.
2 варианта: либо вручную использовать замену апострофов на двойные апострофы, либо использовать sqlEscapeString.
0
androbro
355 / 312 / 71
Регистрация: 17.10.2014
Сообщений: 915
12.11.2014, 17:00 13
А они бэкслэшем не экранируются
Java
1
String name = \'Этуаль";
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
12.11.2014, 17:07 14
androbro, это не имеет смысла, потому что SQL не будет обращать внимания на "\'". Он будет обращать внимание, если распознает такое:
SQL
1
2
WHERE name = 'Л'Этуаль'
WHERE name = 'Л\'Этуаль'
0
Rube
912 / 560 / 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
325 / 123 / 10
Регистрация: 01.11.2012
Сообщений: 586
14.11.2014, 08:38 16
Вместо конкретного символа используйте его UNICODE представление. Например, для LIKE '%слово%' тоже ругался на знак процента. Написав его в unicode, все прошло как по маслу. Правда, если заранее не знаете какие символы, то нужно делать проверку и замену. Удачи.
1
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
14.11.2014, 13:43 17
Я не понимаю, над чем до сих пор мучаетесь. Процент, конечно же, прекрасно работает в SQL-запросе, если запрос написан по правилам. Например, "WHERE LIKE '%%аб%'". Ещё есть вероятность получить SQL-инъекцию, но sqlEscapeString должна решать и этот вопрос.
1
Rube
912 / 560 / 88
Регистрация: 13.02.2014
Сообщений: 2,074
14.11.2014, 13:53  [ТС] 18
Цитата Сообщение от CoolMind Посмотреть сообщение
Я не понимаю, над чем до сих пор мучаетесь.
Это dubok79 мучается, я же проблему давно решил двумя постами выше.
0
dubok79
325 / 123 / 10
Регистрация: 01.11.2012
Сообщений: 586
14.11.2014, 14:02 19
Я не мучаюсь, а предложил свой вариант, который тоже работает. Почему так, потому что с MySQL постольку поскольку, а в нем видать есть методы мне не известные и похоже вам тоже.
0
CoolMind
422 / 404 / 66
Регистрация: 06.10.2012
Сообщений: 1,735
15.11.2014, 13:00 20
dubok79, кстати, хорошо, что вы написали про процент. Проверил, действительно, процент не ищет, находит в итоге все записи. Я чего-то про такой вариант даже и не думал. Попробую ваш вариант.
0
15.11.2014, 13:00
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2014, 13:00

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

Накладывание изображений или "надевание" на нарисованного героя "доспехи"
Моя задача, если выдернуть ее из общего контекста идеи: Создаётся герой, в бд записываются все...

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


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

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

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