Mirra88
Постоялец
Offline
|
|
« : 20-07-2011 15:06 » |
|
Кто-нибудь знает как в Builder6, в базах данных реализуется быстрый поиск (набираю "А" появляются все записи на эту букву, и т. д.)? Что-то я не нашла в Builder6 подобного элемента..
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 20-07-2011 15:22 » |
|
В OnChange простого текстового поля делаешь обновление списка результатов. Только остерегайся с большими списками так работать.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #2 : 20-07-2011 15:27 » |
|
Спасибо. Речь как раз о боьшом списке, о справочнике ОКАТО. 3245 страниц текста...
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #3 : 20-07-2011 18:55 » |
|
Тогда проверяй, что пользователь ввел хотя бы два, а лучше три символа (опытным путем определится, сколько надо) и только потом производи подгрузку из базы. И не забудь в противном случае очистить список, чтобы сохранить логичность реакций на действия.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #4 : 21-07-2011 03:56 » |
|
я бы всё разом загрузил в память, ну съешь ты 10 мегабайт, кто их сейчас считает просто если БД будет долго отвечать, то может быть не очень хорошая картина а еще можно делать так как делают поисковики, они показывают 10 подсказок(вероятно топ популярных или произвольную выборку из топа), которые по мере набора уточняются кстати эта штука называется - саджест
|
|
|
Записан
|
Странно всё это....
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 21-07-2011 06:04 » |
|
Я думаю, справочник ОКАТО не обновляется каждую минуту и даже каждый час. Поэтому вполне разумно в начале работы его выгрузить в память - закэшировать (10 Мб, действительно, не проблема) и затем уже работать с этой копией.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #6 : 21-07-2011 06:25 » |
|
"В начале работы справочник надо выгрузить в память" - такая фраза логичная. Но я не понимаю, а что есть возможность самой из конкретной среды управлять оперативной памятью? Как это сделать, как я могу сказать приложению, что вот эту переменную, или таблицу, или что-то ещё я в оперативной памяти видеть хочу, а вот эту - нет. Мне казалось, что это делает сама операционная система, автоматически.
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #7 : 21-07-2011 07:48 » |
|
Не вижу смысла всю БД в память загонять. Фишка использования БД - это возможность поиска и получения нужной выборки. Для данной задачи получения большой выборки в текстовом поле, можно сделать следующее: 1. Делаем последовательно выборки ограниченные, к примеру 100 записями и загоняем их в память (массив) 2. Параллельно выводим сначала первых 100 записей в текстовое поле. Затем по мере прокрутки пользователем этого текстового поля, подгружаем из массива новые данные.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #8 : 21-07-2011 09:18 » |
|
zubr, зачем впадать в крайности? Речь идёт о конкретном справочнике, по которому надо организовать поиск по мере набора. Может о нескольких таких справочниках, но не о "всей БД". Главными условиями являются: необходимость частых запросов, с частотой около 1 с и менее по всему объёму, "стабильность" данных справочника (преимущественно чтение, изменения данных происходят очерь редко и/или по особому расписанию автоматически). Но я не понимаю, а что есть возможность самой из конкретной среды управлять оперативной памятью? Как это сделать, как я могу сказать приложению, что вот эту переменную, или таблицу, или что-то ещё я в оперативной памяти видеть хочу, а вот эту - нет. Мне казалось, что это делает сама операционная система, автоматически. А я не понимаю, причём тут операционная система? Это прикладное приложение (наверняка desktop), работа с БД. О какой среде идёт речь?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #9 : 21-07-2011 11:01 » |
|
Работу с базой данных (в данном случае я отлаживаю работу с одной-единственной таблицей - справочником ОКАТО (справочником территорий), чтобы с ним удобно было работать при вводе в базу данных жителей любого города) я организовываю средствами среды Builder6. При этом сама таблица кодов ОКАТО может быть и не активной, ибо, всё-таки, в любом населённом пункте преобладают по большей части местные жители, и зачем тогда 24 часа в сутки держать таблицу активной если иногородний может появиться, скажем, раз в восемь часов или вообще не появиться? Но при каком то событии (скажем, при щелчке правой кнопкой мыши по спец. полю) табличка должна активироваться и показывать свои записи, чтобы оператор мог выбрать населённый пункт. Выбирать из миллиона записей навигатором или прокруткой нереально долго. Можно просто ввести в спец. поле необходимый населённый пункт, нажать спец кнопку поиска и программа легко отыщет все пункты с данным названием (а "однофамильцев" тут, ну очень много!) и позволит оператору ввести связанный с нужным населённым пунктом ОКАТО в программу. Но, мне кажется, что "ближний поиск" ещё удобнее (оператор просто вводит нужные буквы, а программка сама выводит откорректированный список, ну как в сотовых телефонах ищутся контакты). Так вот если я активирую таблицу, то, если я правильно понимаю, я её как раз загружаю в оперативную память ПК. Причём, независимо от моего желания или среды программирования. В какой бы среде я с базой не работала, активация таблицы означает её загрузку в память. Разве я не права?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #10 : 21-07-2011 11:14 » |
|
Вопрос: ОКАТО и КЛАДР - это разные базы?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #11 : 21-07-2011 11:17 » |
|
Я не знаю, что такое КЛАДР. Месяц назад не знала и что такое ОКАТО, но вот пришлось узнать.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #12 : 21-07-2011 11:27 » |
|
Судя по Вики, это разные базы - одна налоговая, другая административная. Но система у них одна: код делится на фиксированные части, кодирующие узлы дерева. В моей программе с базой КЛАДР я выбираю код города (как правило, в программе по умолчанию уже выбран "свой" город) - появляется в другом combobox список следующего уровня и так далее. Просто и удобно для пользователя. Также организован поиск по полному или частичному коду с выводом кодов и описанием совпавших объектов. Ничего в памяти держать не нужно, кроме текущих наполнений combobox-ов.
|
|
« Последнее редактирование: 21-07-2011 11:31 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Mirra88
Постоялец
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
|
|
« Ответ #14 : 08-08-2011 06:57 » |
|
Никогда не делай прямое добавление текстового поля в запрос! Это дает уязвимость и, как минимум, является источником сбоев. Используй подстановку. Form1->ADOQuery1->Filter = "(Name1 LIKE CONCAT(?, '%'))"; // Form1->ADOQuery1->Paremeters->Clear(); Form1->ADOQuery1->Paremeters->CreateParameter("FILTER", ftString, pdInput, Edit1->Text); В данном примере параметры не именованные - используется шаблон "?" для подстановки по порядку. Почитай документацию - возможно твоя СУБД поддерживает именованные параметры - это удобнее.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #15 : 08-08-2011 08:22 » |
|
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #16 : 08-08-2011 12:10 » |
|
Спасибо, всё это я, конечно, учту, а если найду какое-то более совершенное решение, чем уже нашла, то здесь его приведу.
|
|
|
Записан
|
|
|
|
Mirra88
Постоялец
Offline
|
|
« Ответ #17 : 12-08-2011 17:14 » |
|
На специализированном форуме по Builder мне подсказали замечательное решение. Оно совсем-совсем другое. Используется "ловушка клавиатуры" - функция обработчик события OnKeyPress для элемента TDBGrid. В этой функции перехватываются и запоминаются введённые пользователем символы, которые посылаются как параметр по значению в самописную функцию инкрементного поиска. А функция инкрементного поиска заканчивается функцией вида: ADOQuery1->Locate("Name1", (Variant)asSearchVal, loSearch); где (Variant)asSearchVal - как раз введённые пользователем для поиска по полю Name1 символы, а loSearch - дополнительные параметры поиска, такие как надо-ли учитывать регистр. Тут и с точки зрения безопасности всё соблюдено (тут же ведь не опасно прямое добавления текстового поля в запрос, ибо конечный запрос тут специфический и опосредованный), и работает быстро, и для пользователя удобнее, потому что он может работать помимо своей и со ВСЕМИ остальными записями (а не только отфильтрованными). Ну как в инкрементном поиске сотового телефона.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #18 : 12-08-2011 19:39 » |
|
Locate ищет в Dataset, но не в базе. Надеюсь, ты это понимаешь. Чтобы искать с его помощью придется загрузить всю таблицу, а не отдельные строки, согласно фильтру. Не советую так поступать с таблицами более пары тысяч строк - будет медленно работать.
|
|
« Последнее редактирование: 12-08-2011 19:42 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|