Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: 6468
Последний выпуск: 19.06.2015

Поиск строки без учета регистра sqlite

326
16 июня 2013 года
kastron
215 / / 17.09.2006
Здравствуйте, уважаемые форумчане! Пытаюсь разобраться с SQL в Delphi. Набросал простенькую таблицу с двумя параметрами: ФИО и номер телефона.
Возник следующий вопрос: при попытке поиска по параметру "фио" обнаружил, что поиск чувствителен к регистру (в плане кириллицы, для латиницы подобной ситуации нет). В качестве конкретного примера интересует найти фамилию Петров/Сидоров по запросу "си" или "пе".
На данный момент мне это не удается. Помогите пожалуйста разобраться.
Исходный код прилагается. Спасибо.
Прикрепленные файлы:
240 Кб
Загрузок: 256
411
17 июня 2013 года
CassandraDied
763 / / 24.05.2012
Цитата:
поиск чувствителен к регистру (в плане кириллицы, для латиницы подобной ситуации нет)


Баг SQLite. Не знаю, пофиксили ли её. Попробуй выключить эту прагму PRAGMA case_sensitive_like, она должна сделать все сравнения с помощью LIKE нечувствительными к регистру, но может и не сработать.
А вообще, лучше все вещи хранить в базе в одном регистре, в нижнем, например, а уже при выводе в форму менять его.
Либо, касательно SQLite, можно использовать функцию lower(), но это замедлит поиск.
Алсо, если будешь юзать lower(), она будет работать только для ASCII символов по дефолту, для всего, что вне ASCII, надо подключить ICU экстеншон.
Да чего я тебе всё это рассказываю? Ты и сам можешь это прочесть в документации к СУБД,

326
18 июня 2013 года
kastron
215 / / 17.09.2006
CassandraDied, PRAGMA case_sensitive_like нужно указать на этапе запроса на поиск в строке
 
Код:
sql_tb:=sql.GetTable('SELECT fio,tel FROM users WHERE fio LIKE "%'+Utf8Encode(find_edit.Text)+'%" PRAGMA case_sensitive_like ');
?
или каким-либо другим образом?
411
18 июня 2013 года
CassandraDied
763 / / 24.05.2012
Клац.
Первая и вторая статьи тоже обязательны к прочтению.
326
28 июня 2013 года
kastron
215 / / 17.09.2006
Попробовал с RU_CollationCompare - результат тот же.
 
Код:
function RU_CollationCompare(UserData: pointer; l1: integer; p1: pointer; l2: integer; p2: pointer): integer; cdecl;
begin
  result := CompareUTF8IgnoreCase(L1, P1, L2, P2);
end;
еще проверял UnicodeCompare
 
Код:
function UnicodeCompare(UserData: Pointer; P1Size: Integer;
  P1: PWideChar; P2Size: Integer; P2: PWideChar): Integer; cdecl;
begin
  Result := CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
    P1, P1Size div SizeOf(WideChar), P2, P2Size div SizeOf(WideChar)) - CSTR_EQUAL;
end;
sqlite3_create_collation(FDB, 'RU', 1, nil, @UnicodeCompare);
безрезультатно

так тоже не выходит

 
Код:
sqlite3_create_collation(FDB, 'RU', 1, nil, @RU_CollationCompare);
 
Код:
sqlite3_create_collation(FDB, 'RU', 1, nil, RU_CollationCompare);
а так требует указать параметры для RU_CollationCompare
463
28 июня 2013 года
QWERYTY
595 / / 25.03.2012
Зачем UnicodeCompare такая сложная? Да еще возможно с ошибками.

Я бы сделал так:
 
Код:
function WideCompareWithoutCase(lpStr1: PWideChar; lpStr2: PWideChar): INTEGER;
begin
   Result := CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, lpStr1, Length(lpStr1), lpStr2, Length(lpStr2));
end;
У меня в XP работает чётко. При одинаковых словах и разных регистрах символов выдаёт CSTR_EQUAL
Обратите внимание на использование Length. Это накладывает некоторые ограничения на функцию, но с практической точки зрения я думаю мало вероятно встретить фамилию из 65536 символов.
326
01 октября 2013 года
kastron
215 / / 17.09.2006
Цитата: QWERYTY
Зачем UnicodeCompare такая сложная? Да еще возможно с ошибками.

Я бы сделал так:
 
Код:
function WideCompareWithoutCase(lpStr1: PWideChar; lpStr2: PWideChar): INTEGER;
begin
   Result := CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, lpStr1, Length(lpStr1), lpStr2, Length(lpStr2));
end;
У меня в XP работает чётко. При одинаковых словах и разных регистрах символов выдаёт CSTR_EQUAL
Обратите внимание на использование Length. Это накладывает некоторые ограничения на функцию, но с практической точки зрения я думаю мало вероятно встретить фамилию из 65536 символов.



Попробовал так, как ты написал... Все равно не находит Сидорова через "си"

Прикрепленные файлы:
250 Кб
Загрузок: 206
463
04 октября 2013 года
QWERYTY
595 / / 25.03.2012
А код можно глянуть?

Вот фрагмент где вы считываете фамилию, обрезаете её длину до длины поискового слова и потом пытаетесь применить функцию.

Я думаю понятно что при разных длинах слова не равны?
326
09 октября 2013 года
kastron
215 / / 17.09.2006
Цитата: QWERYTY
А код можно глянуть?

Вот фрагмент где вы считываете фамилию, обрезаете её длину до длины поискового слова и потом пытаетесь применить функцию.

Я думаю понятно что при разных длинах слова не равны?



Код в приложении к моему предыдущему посту.
Не совсем понимаю где "считываю фамилию" вот основной запрос

 
Код:
sql_tb:=sql.GetTable('SELECT fio,tel FROM users WHERE fio LIKE "%'+Utf8Encode(find_edit.Text+'%"'));
326
09 октября 2013 года
kastron
215 / / 17.09.2006
Попробовал тоже самое, но с LOWER(FIO) и AnsiLowerCase(find_edit.text) и без Utf8Encode/Utf8Decode при записи/чтении из базы.
Результат по поиску - тот же.
Прикрепленные файлы:
219 Кб
Загрузок: 216

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог