Конференция "Начинающим" » регистронезависимый запрос SQL (Absolute DB или Accuracer) [D7, Absolute DB]
 
  • pooh001 © (17.03.12 22:32) [0]
    Помогите разобраться как реализовать регистронезависимый запрос в Absolute DB или Accuracer DB), у меня есть таблица tTable:

    ID Name
    1 имя
    2 ИМЯ
    3 Имя
    4 иМя
    5 имЯ

    есть индекс iNoCase в котором отключена чувствительность к регистру для поля Name.

    реализую простейший запрос через TABSQuery

    ABSQuery.SQL.Clear;
    ABSQuery.SQL.Add('SELECT Name,ID FROM tTable WHERE Name="имя"');
    ABSQuery.SQL.Open;

    В результате он мне выдает только первую строку таблицы. Как мне сделать чтоб он выдавал все совпадения не смотря на регистр? И еще, не совсем понятно пока как задействовать в запросах созданный регистронезависимый индекс iNoCase.

    UPPER не подходит для решения проблемы. если сделать так: SELECT Name,ID FROM Table WHERE UPPER(Name)=UPPER("имя"), начинает заметно тормозить.
  • Anatoly Podgoretsky © (17.03.12 22:49) [1]
    > pooh001  (17.03.2012 22:32:00)  [0]

    Почему WHERE UPPER(Name)=UPPER("имя"), а не WHERE UPPER(Name)="ИМЯ"
  • pooh001 © (17.03.12 23:10) [2]
    Потому, что пользователь вводит параметры запроса через едит и в основном без учета регистра, а в базе информация хранится в произвольном регистре. хотелось более красиво решить эту проблему, без принудительного изменения регистра. Не очень красиво получится если хранить все в базе в одном регистре и переводить все что ввел пользователь в тот же регистр

    в простейшем виде запрос в программе происходит так:
    ABSQuery.SQL.Clear;
    ABSQuery.SQL.Add('SELECT Name,ID FROM tTable WHERE Name LIKE :pName + \"%\"');
    ABSQuery.ParamByName('pName').AsString := edName.Text;
    ABSQuery.SQL.Open;

  • Anatoly Podgoretsky © (18.03.12 00:27) [3]
    Это уже совсем другой запрос, ты специально запутываешь?
  • Кщд (18.03.12 08:59) [4]
    >pooh001 ©   (17.03.12 23:10) [2]
    >Не очень красиво получится если хранить все в базе в одном регистре
    в чем "некрасота"?
  • sniknik © (18.03.12 10:57) [5]
    > в чем "некрасота"?
    вообще, если есть регистро-независимый(/любой) индекс, и он по какой то причине не работает, то это действительно не хорошо...
  • pooh001 © (18.03.12 15:14) [6]
    Не красота в том, что теряется гибкость. получается как-то тапорно когда все символы одного регистра. ИВАНОВ ИВАН ИВАНОВИЧ и Ивинов Иван Иванович, помоему есть разница. В БД есть механизмы отключения регистра, просто я не знаю как их задействовать. И с индексом не могу разобраться.
    У меня щас вот так:
    ABSQuery.SQL.Clear;
    ABSQuery.SQL.Add('SELECT Name,ID FROM tTable WHERE UPPER(Name) LIKE UPPER(:pName) + "%"');
    ABSQuery.ParamByName('pName').AsString := edName.Text;
    ABSQuery.SQL.Open;
    но когда объем данных увеличивается, начинает подтормаживать.
    Anatoly Podgoretsky, я не запутываю, просто сразу не уточнил что запрос немного более универсален, пардон.
  • sniknik © (18.03.12 17:57) [7]
    > У меня щас вот так:
    ВНИМАТЕЛЬНО, прочитай Anatoly Podgoretsky ©   (17.03.12 22:49) [1], ПОДУМАЙ, а потом ответь.
  • pooh001 © (18.03.12 18:58) [8]

    > > У меня щас вот так:
    > ВНИМАТЕЛЬНО, прочитай Anatoly Podgoretsky ©   (17.03.12
    > 22:49) [1], ПОДУМАЙ, а потом ответь.

    я внимательно прочитал. отвечаю:потому, что пользователь "БОГ", ему разрешено вводить данные в любом регистре. Программа не препятствует ему. она насильно не повышает регистр символов в едите. Тогда можно было обойтись и без UPPERа, просто хранить все в базе в верхнем регистре и насильно переводить вводимые пользователем данные в верхний.

    сделал так(немного пошустрела скорость формирования запроса):


    > procedure ......................;
    >   function mUpperCase(s: string): string;
    >   var
    >     i: integer;
    >   begin
    >     result := s;
    >     for i := 1 to length(result) do
    >        if (result[i] in ['a'..'z', 'а'..'я'])
    >          then result[i] := chr(ord(result[i]) - 32);
    >   end;
    > begin
    >   ABSQuery.SQL.Clear;
    >   ABSQuery.SQL.Add('SELECT Name,ID FROM tTable WHERE UPPER(Name)
    > LIKE :pName + "%"');
    >   ABSQuery.ParamByName('pName').AsString := mUpperCase(edName.
    > Text);
    >   ABSQuery.SQL.Open;end;
    > end;


    убрал один UPPER и перенес его в едит. да,работает немного быстрее, но не решает проблемы реализации регистронезависимого запроса. это все обход регистра с помощью ухищрений. но ведь это может сделать и сама БД. по крайней мере должна уметь это сделать. может кто сталкивался как заставить ее это сделать.....
  • знайка (18.03.12 21:01) [9]
    в справке должно быть описано
  • sniknik © (18.03.12 21:02) [10]
    > убрал один UPPER и перенес его в едит.
    ???
    какой еще едит? при чем тут "боги" и едиты, тебе про запрос говорили, и только.
    +
    запрос в [0] <> всем последующим. а LIKE кстати и в нормальных базах не всегда индекс использует, а в "твоей" еще вообще вопрос...
  • sniknik © (18.03.12 21:05) [11]
    > сделал так(
    сделал, или тебе сделали? на параллельном форуме где ты еще этот же вопрос задал... даже цитирование не убрал.
    что там за функция такая mUpperCase? объясни нафига? если сам делал.
  • pooh001 © (18.03.12 21:39) [12]

    > знайка   (18.03.12 21:01) [9]
    > в справке должно быть описано

    В справке толком ничего не нашел((


    > sniknik ©   (18.03.12 21:02) [10]
    > sniknik ©   (18.03.12 21:05) [11]

    не пойму что за наезды? едит это TEdit. боги тут не причем, это метафора. Программы делаются для людей, и они должны быть как можно более дружелюбны.
    Не имею желания всупать в конфликты, в поте лица доказывать что сделал я что не я. Функцию mUpperCase нашел в DRKB. Нафига? Стандартная функция UpperCase не переводит в верхний регистр кириллицу.
  • Anatoly Podgoretsky © (18.03.12 21:46) [13]

    > pooh001 ©   (18.03.12 18:58) [8]

    Уже третий код. И зачем ты это делаешь?
  • Anatoly Podgoretsky © (18.03.12 21:48) [14]

    > Стандартная функция UpperCase не переводит в верхний регистр
    > кириллицу.

    Ты справку бы прочитал по данной функции.
  • Anatoly Podgoretsky © (18.03.12 22:00) [15]
    Главное непонятны мучения, когда индекс может быть нечувствителен к регистру.
  • sniknik © (18.03.12 22:07) [16]
    > не пойму что за наезды?
    это не наезды, это ты "тупишь". причем в очевидном, а до разбирательства собственно "не работы индекса" так понимаю вообще не дойдет.

    > Программы делаются для людей, и они должны быть как можно более дружелюбны.
    то, про, что  говорили с интерфейсом ВООБЩЕ не связано. только с запросом/индексами, нет какие то "едиты" приплел.

    > Ты справку бы прочитал по данной функции.
    он ответил заранее
    > В справке толком ничего не нашел((
  • Anatoly Podgoretsky © (18.03.12 22:18) [17]
    Мне больше времени пришлось потратить что бы найти справку по AbsDB, чем на получения ответа. Ответы там лежат на поверхности
  • Кщд (19.03.12 07:39) [18]

    > sniknik ©   (18.03.12 10:57) [5]
    > вообще, если есть регистро-независимый(/любой) индекс, и
    > он по какой то причине не работает, то это действительно
    > не хорошо...

    если есть и не работает - баг, либо руки. тут всё понятно.
    я спрашивал, что "некрасивого" в том, чтобы хранить всё в одном регистре.

    >pooh001 ©   (18.03.12 15:14) [6]
    >получается как-то тапорно когда все символы одного регистра.
    исчерпывающе
  • pooh001 © (19.03.12 11:21) [19]

    > Anatoly Podgoretsky ©   (18.03.12 22:18) [17]
    > Мне больше времени пришлось потратить что бы найти справку
    > по AbsDB, чем на получения ответа. Ответы там лежат на поверхности


    Anatoly Podgoretsky, я немецкий в школе изучал, а справка вся на английском, может чето упустил, может чето не правильно делаю 1) Создал БД. 2) Создал таблицу 3) создал индекс, поставил CaseInsensitive в true. 4) В проекте кинул на форму: ABSDatabase, ABSTable, ABSQuery. Подключил их все. ABSTable.IndexName:=<мой индекс>. 5)Затем формирую запрос. Но он все равно чувствует регистр. И что странно в ABSTable.IndexDefs[<индекс>].Options = [] не отмечен ixCaseInsensitive.
    Может и не правильно чето делаю, я недавно начал изучать БД, да и Delphi
  • Inovet © (19.03.12 11:47) [20]
    > [18] Кщд   (19.03.12 07:39)
    > я спрашивал, что "некрасивого" в том, чтобы хранить всё
    > в одном регистре.

    Ну так действительно "тапорно". Где-то в отчётах лучше видеть ООО "Родинов продакшн", чем в одном регистре, и поправить можно регистр, если что не так.
  • sniknik © (19.03.12 12:15) [21]
    не читая справку, не зная/не работая с Absolute Database, вижу подвох вот тут
    > создал индекс, поставил CaseInsensitive в true
    индекс создан, и создан "на сервере", а "поставил CaseInsensitive" подразумевает, прямо таки напрашивается клиент... т.е. ограниченное локально действие.
    хотя, утверждать по столь красочному, и абсолютно технически безграмотному описанию "создания", ничего нельзя конечно.

    > я недавно начал изучать БД, да и Delphi
    извините, был пьян, за рулем только неделю, поэтому и разгромил ваш магазин... не судите строго...

    блин, и почему не в начинающих?
  • знайка (19.03.12 12:20) [22]
    Еще иногда делают рядом доп. поле где тоже имя хранят в каком-то одном кэйсе, и поиск ведут по нему.
  • sniknik © (19.03.12 12:24) [23]
    > Еще иногда делают рядом доп. поле где тоже имя хранят в каком-то одном кэйсе, и поиск ведут по нему.
    последний раз когда делал так, это в фохпро, в прошлом веке... и то еще до того как узнал, что он позволяет формировать индекс по выражению... (т.е. в самом начале работы с ним).
  • знайка (19.03.12 12:34) [24]
    Microsoft, например, до сих пор так предлагает иногда.
    Вот есть у них заготовка для менеджмента пользователей, так там в таблице
    aspnet_Membership есть такие поля:
    Email nvarchar(256)
    LoweredEmail nvarchar(256)
  • Anatoly Podgoretsky © (19.03.12 12:42) [25]
    CREATE TABLE:
    ...
    and index_definition is:

     [, PRIMARY [ KEY ] [ index_name ] ( column_name  [ ASC | DESC ]  [ CASE | NOCASE ]  [, ... ] ) ]

     [, [ UNIQUE ] [INDEX] [index_name] ( column_name  [ ASC | DESC ]  [ CASE | NOCASE ]  [, ... ] ) ]
  • Anatoly Podgoretsky © (19.03.12 12:45) [26]
    >   ()  []

    MS SQL все нормально работает без дополнительных полей, главное указать
    правильный Location
  • pooh001 © (19.03.12 20:27) [27]
    Использую локальный файл БД. Файл БД был создан с помощью утилиты DBManager. Все таблицы, индексы били созданы с помощью нее же. Не знаю правильно это или нет, но в фале БД все индексы ixCaseInsensitive=true, а программа уже не видит это свойство, т.е. для нее ixCaseInsensitive=false. Фильтры работают нормально, foCaseInsensitive=true и чувствительности к регистру как не бывало. Но необходима отсутствие чувствительности к регистру именно в запросах SQL.
    Чтоб было наглядно сделал небольшой исходничек, чтоб более "напальцах" показать все на примере. Кому не лень посмотрите.
    Ссылка: _http://www.fayloobmennik.net/1682255
    Думаю компоненты Absolute DB есть у всех (_http://www.componentace.com/download/download.php?editionid=1)
  • pooh001 © (19.03.12 20:37) [28]

    > Anatoly Podgoretsky ©   (19.03.12 12:42) [25]
    >
    > CREATE TABLE:
    > ...
    > and index_definition is:
    >   [, PRIMARY [ KEY ] [ index_name ] ( column_name  [ ASC
    > | DESC ]  [ CASE | NOCASE ]  [, ... ] ) ]
    >   [, [ UNIQUE ] [INDEX] [index_name] ( column_name  [ ASC
    > | DESC ]  [ CASE | NOCASE ]  [, ... ] ) ]


    Anatoly Podgoretsky, спасибо, но не работает. Там свой более урезанный язык SQL. В примере (ссылку дал выше),создается индекс 2мя спопобами. c помощью TABSTable и с помощью SQL запроса, в обоих случаях задается нечувствительность к регистру, но она почему-то не работает на деле. Может я чето упускаю. Пол дня сидел на примере все перебирал, пробовал несколько разных версий компонентов, все одно и тоже. Не пойму что я упускаю...
  • sniknik © (19.03.12 22:16) [29]
    чего там урезано? минута "брожения"  на сайте по данной ссылке
    http://www.componentace.com/sql/create-index.htm
    ... for field "name" sorting order is descending and is case-insensitive.  ...

    это ДОЛЖНО работать, единственное проверить локализацию, т.е. сначала английские слова в разных регистрах, убедится что действительно работает, а после туда же русские добавить и проверить...
    еще раз убедится, т.к. вот тут это написано прямым текстом
    http://www.componentace.com/absolute_database_features.htm
    Internationalization / localization support by use of current system locale
  • sniknik © (19.03.12 22:20) [30]
    > Думаю компоненты Absolute DB есть у всех
    оптимист. и даром не надь... (ставить левые компоненты в систему)
  • Inovet © (19.03.12 22:37) [31]
    > [27] pooh001 ©   (19.03.12 20:27)
    > Думаю компоненты Absolute DB есть у всех

    Ты очень самоуверен.
  • Кщд (20.03.12 09:25) [32]
    >Inovet ©   (19.03.12 11:47) [20]
    >Ну так действительно "тапорно". Где-то в отчётах лучше видеть ООО "Родинов продакшн"

    если нет индексов по выражению или регистронезависимых, то "как-то тапорно" не аргумент против падения производительности на запросах where NAME = :p.
    и, если честно, вообще не аргумент)
    там, где это принципиально важно - можно, как было предложено, хранить в доп. поле в upper(lower) case или в виде хэша(md5)
    но, простите, например поступать так, например, с email - на мой взгляд, неоправданно
    если есть контрпримеры, с удовольствием выслушаю
  • Inovet © (20.03.12 10:30) [33]
    > [32] Кщд   (20.03.12 09:25)

    Про производительность согласен, если нет возможности. а вот с "и, если честно, вообще не аргумент" - не согласен. В печатных и электронных документах навименования должно быть в соответсвии правилами языка и, например, учредительных документов, данных паспорта, не помню, есть ли такое требование в законодательстве.

    Другое дело, что для поиска можно сделать второе наименование, и даже нужно. Вот в это поле и писать что угодно-удобно. Лучше видеть отсортированным по названию, чем по ООО, ОАО, ЧП и т.п.. Это для примера, конечно. Для адреса емайл такое ни к чему.
  • Кщд (20.03.12 10:39) [34]
    >Inovet ©   (20.03.12 10:30) [33]
    >В печатных и электронных документах навименования должно быть в >соответсвии правилами языка и, например, учредительных документов,

    в Кщд   (20.03.12 09:25) [32]:
    "там, где это принципиально важно - можно" - и нужно
    "но, простите, поступать так, например, с email - на мой взгляд, неоправданно"
  • Inovet © (20.03.12 11:58) [35]
    > [34] Кщд   (20.03.12 10:39)

    В общем ShorName надо для таких случаев. Всё уже придумано.
  • Inovet © (20.03.12 12:00) [36]
    > [34] Кщд   (20.03.12 10:39)

    Да. Про адрес эл. почты не я писал, если что.
  • pooh001 © (20.03.12 12:23) [37]

    > sniknik ©   (19.03.12 22:16) [29]
    >
    > чего там урезано? минута "брожения"  на сайте по данной
    > ссылке
    > http://www.componentace.com/sql/create-index.htm
    > ... for field "name" sorting order is descending and is
    > case-insensitive.  ...
    >
    > это ДОЛЖНО работать, единственное проверить локализацию,
    >  т.е. сначала английские слова в разных регистрах, убедится
    > что действительно работает, а после туда же русские добавить
    > и проверить...
    > еще раз убедится, т.к. вот тут это написано прямым текстом
    > http://www.componentace.com/absolute_database_features.htm
    > Internationalization / localization support by use of current
    > system locale


    пробовал тот пример по первой ссылке. у меня билин не работает это. И не устанавливается у меня ixCaseInsensitive хоть тыбилин лопни. Какую-то мелочь упускаю видимо.
    Пробовал как ты сказал "сначала английские слова в разных регистрах" - не работает. Фильтры работают красиво. Запрос нет.
    Про локализацию смутно знаю. если это:

    > - кодовый набор
    >  - схема сортировки
    >  - классификация символов
    >  - числовое (не денежное) форматирование
    >  - денежное форматирование
    >  - форматирование даты и времени
    >  - сообщения

    То все установлено по умолчанию (OS Windows 7 Ultimate Russian x86)

    Наверное возьму переводчик, и попробую написать им в поддержку.
  • Inovet © (20.03.12 12:29) [38]
    > [37] pooh001 ©   (20.03.12 12:23)

    Ты создай таблицу и индекс не из визуальной прилады, а запросом, для начала. Потм с локалью посмотри в запросе DDL же.
  • pooh001 © (20.03.12 12:57) [39]

    > Inovet ©   (20.03.12 12:29) [38]
    > Ты создай таблицу и индекс не из визуальной прилады, а запросом,
    >  для начала. Потм с локалью посмотри в запросе DDL же.


    Создавал индекс тремя способами 1)при создании файла БД 2) с помощью TABSTable 3) с помощью запроса SQL(в исходнике прикрепленном выше это есть). Ни в одном случае не помогло.

    Создавал запросом таблицу и индекс как описано на оффсайте (http://www.componentace.com/sql/create-index.htm), только последнюю строчку заменил на select name,code from developers where name="janet" order by name; не находит он жанету. меняю name="Janet"(с большой буквы)-находит.

    спасибо за советы. если разберусь напишу в чем была проблема.
 
Конференция "Начинающим" » регистронезависимый запрос SQL (Absolute DB или Accuracer) [D7, Absolute DB]
Есть новые Нет новых   [134431   +13][b:0][p:0.001]