SQLite LIKE без чувствительности к регистру текста

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Ответить
bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

SQLite LIKE без чувствительности к регистру текста

Сообщение bagrusss » 13 окт 2014, 16:44

Выполняю вот такой запрос:

Код: Выделить всё

SELECT * FROM friends WHERE UPPER(fname) like '%SOME_VAL%' ORDER BY _id
Но в курсоре не все, что должно подходить по условию. Например, похожий запрос работает на ура вот здесь:
пример
Я так понял, что проблема в чуствительности. Добавил UPPER для столбца, но он не срабатывает почему-то для запроса.

Как мне выбрать все записи из таблицы вхождением подстроки в строку в независимости от регистра текста?

endid13
Сообщения: 16
Зарегистрирован: 26 сен 2014, 16:34

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение endid13 » 13 окт 2014, 20:50

Попробуйте так:

Код: Выделить всё

query("SELECT * FROM friends WHERE UPPER(fname) like ? ORDER BY _id", new String[] { SOME_VAL.toUpperCase(Locale.getDefault()) }

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение bagrusss » 13 окт 2014, 21:32

endid13 писал(а):Попробуйте так:

Код: Выделить всё

query("SELECT * FROM friends WHERE UPPER(fname) like ? ORDER BY _id", new String[] { SOME_VAL.toUpperCase(Locale.getDefault()) }
Ваше решение, к сожалению, не работает ( :cry: ), даже если его модифицировать вот так:

Код: Выделить всё

db.rawQuery("SELECT * FROM friends WHERE Upper(fname) like ? ORDER BY _id COLLATE NOCASE", new String[] { "'%"+val.toUpperCase(Locale.getDefault())+"%'" });
Почему-то Upper не срабатывает для fname...

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение Foenix » 13 окт 2014, 21:50

не сработает он для русских букв, или будет работать криво.
Самый простой выход - это держать столбец в одном из режимов - только большие буквы, например, и сравнивать по нему.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение bagrusss » 13 окт 2014, 21:55

Foenix писал(а):держать столбец в одном из режимов - только большие буквы, например, и сравнивать по нему.
Идея ясна. Придется костыли писать...
Последний раз редактировалось bagrusss 14 окт 2014, 00:20, всего редактировалось 1 раз.

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение bagrusss » 14 окт 2014, 00:19

Нашел несколько решений:
1. https://gist.github.com/ramzes642/5400792
2. http://habrahabr.ru/post/122408/
3. Добавлять еще один столбец, в котором хранить данные в верхнем/нижнем регистре и искать соответственно.

Вопрос можно считать закрытым.

endid13
Сообщения: 16
Зарегистрирован: 26 сен 2014, 16:34

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение endid13 » 18 окт 2014, 16:50

Если будет интересно, вот так я переводил в таблице все буквы к одному регистру:

Код: Выделить всё

public void dbUpdate() {
        database = dbHelper.getReadableDatabase();
        ContentValues cv = new ContentValues();
        String buff_read ;
        String buff_write;
        boolean changed;        // Флаг замены символа

        String from =   "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";     // Преобразование
        String to =     "абвгдежзийклмнопрстуфхцчшщъыьэюя";     // в нижний регистр

        String table = "название таблицы";
        String[] columns = { "_id", названия столбцов для преобразования };

        String id = "";

        Cursor cursor = database.query(table, columns, null, null, null, null, null);

        if (cursor.moveToFirst()) {
            do {
                cv.clear();
                // Перебираем все столбцы
                for (String col_name : cursor.getColumnNames()) {
                    if (col_name.equals(columns[0])) {
                        id = cursor.getString(cursor.getColumnIndex(col_name));
                    } else {
                        // Получаем содержимое ячейки, обнуляем буфер записи
                        buff_read = cursor.getString(cursor.getColumnIndex(col_name));
                        buff_write = "";
                        // Перебираем содержимое ячейки посимвольно
                        for (int i = 0; i < buff_read.length(); i++) {
                            changed = false;
                            // Перебираем все символы из from на совпадение
                            for (int j = 0; j < from.length(); j++) {
                                if (buff_read.charAt(i) == from.charAt(j)) {
                                    // Если совпадение есть - добавляем символ в буффер
                                    buff_write += to.charAt(j);
                                    changed = true;
                                    break;
                                }
                            }
                            if (!changed) {
                                // Если нет совпадения - пропускаем символ
                                buff_write += buff_read.charAt(i);
                            }
                        }
                        cv.put(col_name, buff_write);
                    }
                }
                database.update(table, cv, columns[0] + " = ?", new String[] { id });
                Log.d("log_tag", "updated row id = " + id);
            } while (cursor.moveToNext());
        }
    }
Если база большая - лучше положить в AsyncTask. И сохранять id последней записи на случай, если вдруг процесс прервется. Чтобы с начала не начинать.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение Foenix » 18 окт 2014, 18:41

та ты что? издеваешься??????????
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

endid13
Сообщения: 16
Зарегистрирован: 26 сен 2014, 16:34

Re: SQLite LIKE без чувствительности к регистру текста

Сообщение endid13 » 23 окт 2014, 17:09

Ну не придумал я ничего получше. Ну разве что получать не всю базу, а сначала сгрузить все id в массив и потом перебирая этот массив заносить в курсор соответствующую строку из базы.
А какие еще есть варианты решения? Кроме подключения нативной библиотеки на си?
Уточню. Допустим, база уже существует, в ней строки, содержащие символы в разных регистрах. И не обязательно в верхнем регистре будет только первая заглавная буква

Ответить