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

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

ru
Offline Offline

« : 20-07-2011 15:06 » 

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

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

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

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

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

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Mirra88
Постоялец

ru
Offline Offline

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

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

ru
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
Команда клуба

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

« Ответ #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
Технический
Администратор

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

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

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

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

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Mirra88
Постоялец

ru
Offline Offline

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

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

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

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

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


* kladr_dialog.png (12.86 Кб - загружено 1143 раз.)
« Последнее редактирование: 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
Технический
Администратор

ru
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
Технический
Администратор

ru
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