Страница 1 из 1

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

Добавлено: 13 окт 2014, 16:44
bagrusss
Выполняю вот такой запрос:

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

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

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

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

Добавлено: 13 окт 2014, 20:50
endid13
Попробуйте так:

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

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

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

Добавлено: 13 окт 2014, 21:32
bagrusss
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...

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

Добавлено: 13 окт 2014, 21:50
Foenix
не сработает он для русских букв, или будет работать криво.
Самый простой выход - это держать столбец в одном из режимов - только большие буквы, например, и сравнивать по нему.

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

Добавлено: 13 окт 2014, 21:55
bagrusss
Foenix писал(а):держать столбец в одном из режимов - только большие буквы, например, и сравнивать по нему.
Идея ясна. Придется костыли писать...

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

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

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

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

Добавлено: 18 окт 2014, 16:50
endid13
Если будет интересно, вот так я переводил в таблице все буквы к одному регистру:

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

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 последней записи на случай, если вдруг процесс прервется. Чтобы с начала не начинать.

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

Добавлено: 18 окт 2014, 18:41
Foenix
та ты что? издеваешься??????????

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

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