Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Быстрый поиск в базах данных Builder6  (Прочитано 27889 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
Mirra88
Постоялец

ru
Offline Offline

« : 20-07-2011 15:06 » 

Кто-нибудь знает как в Builder6, в базах данных реализуется быстрый поиск (набираю "А" появляются все записи на эту букву, и т. д.)? Что-то я не нашла в Builder6 подобного элемента..
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 20-07-2011 15:22 » 

В OnChange простого текстового поля делаешь обновление списка результатов. Только остерегайся с большими списками так работать.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Mirra88
Постоялец

ru
Offline Offline

« Ответ #2 : 20-07-2011 15:27 » 

Спасибо. Речь как раз о боьшом списке, о справочнике ОКАТО. 3245 страниц текста...
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 20-07-2011 18:55 » 

Тогда проверяй, что пользователь ввел хотя бы два, а лучше три символа (опытным путем определится, сколько надо) и только потом производи подгрузку из базы. И не забудь в противном случае очистить список, чтобы сохранить логичность реакций на действия.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #4 : 21-07-2011 03:56 » 

я бы всё разом загрузил в память, ну съешь ты 10 мегабайт, кто их сейчас считает Улыбаюсь
просто если БД будет долго отвечать, то может быть не очень хорошая картина
а еще можно делать так как делают поисковики, они показывают 10 подсказок(вероятно топ популярных или произвольную выборку из топа), которые по мере набора уточняются

кстати эта штука называется - саджест Улыбаюсь
Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 21-07-2011 06:04 » 

Я думаю, справочник ОКАТО не обновляется каждую минуту и даже каждый час. Поэтому вполне разумно в начале работы его выгрузить в память - закэшировать (10 Мб, действительно, не проблема) и затем уже работать с этой копией.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Mirra88
Постоялец

ru
Offline Offline

« Ответ #6 : 21-07-2011 06:25 » 

"В начале работы справочник надо выгрузить в память" - такая фраза логичная. Но я не понимаю, а что есть возможность самой из конкретной среды управлять оперативной памятью? Как это сделать, как я могу сказать приложению, что вот эту переменную, или таблицу, или что-то ещё я в оперативной памяти видеть хочу, а вот эту - нет. Мне казалось, что это делает сама операционная система, автоматически.
Записан
zubr
Гость
« Ответ #7 : 21-07-2011 07:48 » 

Не вижу смысла всю БД в память загонять. Фишка использования БД - это возможность поиска и получения нужной выборки.
Для данной задачи получения большой выборки в текстовом поле, можно сделать следующее:
1. Делаем последовательно выборки ограниченные, к примеру 100 записями и загоняем их в память (массив)
2. Параллельно выводим сначала первых 100 записей в текстовое поле. Затем по мере прокрутки пользователем этого текстового поля, подгружаем из массива новые данные.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 21-07-2011 09:18 » 

zubr, зачем впадать в крайности? Речь идёт о конкретном справочнике, по которому надо организовать поиск по мере набора. Может о нескольких таких справочниках, но не о "всей БД".

Главными условиями являются: необходимость частых запросов, с частотой около 1 с и менее по всему объёму, "стабильность" данных справочника (преимущественно чтение, изменения данных происходят очерь редко и/или по особому расписанию автоматически).

Цитата: Mirra88
Но я не понимаю, а что есть возможность самой из конкретной среды управлять оперативной памятью? Как это сделать, как я могу сказать приложению, что вот эту переменную, или таблицу, или что-то ещё я в оперативной памяти видеть хочу, а вот эту - нет. Мне казалось, что это делает сама операционная система, автоматически.
А я не понимаю, причём тут операционная система? Это прикладное приложение (наверняка desktop), работа с БД. О какой среде идёт речь?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Mirra88
Постоялец

ru
Offline Offline

« Ответ #9 : 21-07-2011 11:01 » 

Работу с базой данных (в данном случае я отлаживаю работу с одной-единственной таблицей - справочником ОКАТО (справочником территорий), чтобы с ним удобно было работать при вводе в базу данных жителей любого города) я организовываю средствами среды Builder6. При этом сама таблица кодов ОКАТО может быть и не активной, ибо, всё-таки, в любом населённом пункте преобладают по большей части местные жители, и зачем тогда 24 часа в сутки держать таблицу активной если иногородний может появиться, скажем, раз в восемь часов или вообще не появиться? Но при каком то событии (скажем, при щелчке правой кнопкой мыши по спец. полю) табличка должна активироваться и показывать свои записи, чтобы оператор мог выбрать населённый пункт. Выбирать из миллиона записей навигатором или прокруткой нереально долго. Можно просто ввести в спец. поле необходимый населённый пункт, нажать спец кнопку поиска и программа легко отыщет все пункты с данным названием (а "однофамильцев" тут, ну очень много!) и позволит оператору ввести связанный с нужным населённым пунктом ОКАТО в программу. Но, мне кажется, что "ближний поиск" ещё удобнее (оператор просто вводит нужные буквы, а программка сама выводит откорректированный список, ну как  в сотовых телефонах ищутся контакты). Так вот если я активирую таблицу, то, если я правильно понимаю, я её как раз загружаю в оперативную память ПК. Причём, независимо от моего желания или среды программирования. В какой бы среде я с базой не работала, активация таблицы означает её загрузку в память. Разве я не права?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 21-07-2011 11:14 » 

Вопрос: ОКАТО и КЛАДР - это разные базы?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Mirra88
Постоялец

ru
Offline Offline

« Ответ #11 : 21-07-2011 11:17 » new

Я не знаю, что такое КЛАДР. Месяц назад не знала и что такое ОКАТО, но вот пришлось узнать.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 21-07-2011 11:27 » 

Судя по Вики, это разные базы - одна налоговая, другая административная. Но система у них одна: код делится на фиксированные части, кодирующие узлы дерева.
В моей программе с базой КЛАДР я выбираю код города (как правило, в программе по умолчанию уже выбран "свой" город) - появляется в другом combobox список следующего уровня и так далее. Просто и удобно для пользователя. Также организован поиск по полному или частичному коду с выводом кодов и описанием совпавших объектов. Ничего в памяти держать не нужно, кроме текущих наполнений combobox-ов.


* kladr_dialog.png (12.86 Кб - загружено 2770 раз.)
« Последнее редактирование: 21-07-2011 11:31 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Mirra88
Постоялец

ru
Offline Offline

« Ответ #13 : 21-07-2011 11:41 » 

Спасибо! Сейчас всё это осмыслю и что-нибудь смудрю...

Добавлено через 17 дней, 15 часов, 8 минут и 48 секунд:
Большое спасибо за помощь! Проблему удалось решить двумя способами.
1 Фильтрацией:
Код:
Form1->ADOQuery1->Filter = "(Name1 LIKE '"+ Edit1->Text + "%')";
2 Запросом:
Код:
"ADOQuery1->SQL->Text = "Select *from OKATOTFTAT where Name1 like '"+textEdit+"%'"; 
С помощью запроса работает гораздо медленнее, чем с фильтром.
« Последнее редактирование: 08-08-2011 02:49 от Mirra88 » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 08-08-2011 06:57 » 

Никогда не делай прямое добавление текстового поля в запрос! Это дает уязвимость и, как минимум, является источником сбоев. Используй подстановку.

Код: (C++)
Form1->ADOQuery1->Filter = "(Name1 LIKE CONCAT(?, '%'))";
// Form1->ADOQuery1->Paremeters->Clear();
Form1->ADOQuery1->Paremeters->CreateParameter("FILTER", ftString, pdInput, Edit1->Text);

В данном примере параметры не именованные - используется шаблон "?" для подстановки по порядку. Почитай документацию - возможно твоя СУБД поддерживает именованные параметры - это удобнее.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 08-08-2011 08:22 » 

Mirra88, и почитай про SQL-injection
http://ru.wikipedia.org/wiki/%C2%ED%E5%E4%F0%E5%ED%E8%E5_SQL-%EA%EE%E4%E0
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Mirra88
Постоялец

ru
Offline Offline

« Ответ #16 : 08-08-2011 12:10 » 

Спасибо, всё это я, конечно, учту, а если найду какое-то более совершенное решение, чем уже нашла, то здесь его приведу.
Записан
Mirra88
Постоялец

ru
Offline Offline

« Ответ #17 : 12-08-2011 17:14 » 

 На специализированном форуме по Builder мне подсказали замечательное решение. Оно совсем-совсем другое. Используется "ловушка клавиатуры" - функция обработчик события OnKeyPress для элемента TDBGrid. В этой функции перехватываются и запоминаются введённые пользователем символы, которые посылаются как параметр по значению в самописную функцию инкрементного поиска. А функция инкрементного поиска заканчивается функцией вида:
 
Код:
ADOQuery1->Locate("Name1", (Variant)asSearchVal, loSearch);
где (Variant)asSearchVal - как раз введённые пользователем для поиска по полю Name1 символы, а loSearch - дополнительные параметры поиска, такие как надо-ли учитывать регистр. Тут и с точки зрения безопасности всё соблюдено (тут же ведь не опасно прямое добавления текстового поля в запрос, ибо конечный запрос тут специфический и опосредованный), и работает быстро, и для пользователя удобнее, потому что он может работать помимо своей и со ВСЕМИ остальными записями (а не только отфильтрованными). Ну как в инкрементном поиске сотового телефона.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 12-08-2011 19:39 » 

Locate ищет в Dataset, но не в базе. Надеюсь, ты это понимаешь. Чтобы искать с его помощью придется загрузить всю таблицу, а не отдельные строки, согласно фильтру. Не советую так поступать с таблицами более пары тысяч строк - будет медленно работать.
« Последнее редактирование: 12-08-2011 19:42 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines