|
|
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Здравствуйте всем! Есть такой код: ... qTovar.Close; qTovar.SQL.Clear; qTovar.SQL.Add('SELECT AID, ANAIM, ALEVELS FROM GET_TOVAR_LIST(0,0)'); qTovar.Prepare; qTovar.ExecQuery; //IB Expert возвращает 10 записей if qTovar.RecordCount>0 then //В RecordCount только 1 (!) запись ... Если у qTovar стоит AutoCommit ни одна запись не возвращается. В чем здесь заковыка? Заранее спасибо! З.Ы. qTovar - IBPlus'овский query ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2003, 14:00 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Так никто и не подскажет? :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.05.2003, 11:53 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Для выполнения запросов типа SELECT надо использовать не ExecQuery , а Open ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.05.2003, 12:07 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Вообще-то, кроме Open надо будет еще сделать Last, чтобы в рекордкаунте содержалось действительное число выбранных записей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2003, 09:39 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Привет! Типичная ошибка человека, переезжающго с БДЕ. Код: plaintext 1. 2. 3. 4. 5. Постулаты: 1) В native библиотеках (IBX, FIBPlus и т.д.) необходимо явно управлять транзакциями 2) НЕ следует для подсчета числа записей использовать RecordCount Теория: Когда необходимо выполнить ЛЮБОЙ запрос, действия происходят в таком порядке: 1. Открывается транзакция 2. Текст запроса посылается на сервер и подготалвивается там - разбирается, строится карта использования индексов, формируется план запроса. 3. Параметры запроса посылаются на сервер 4. Запрос выполняется на сервере. 5. Клиентская библиотека начинает выбирать данные запроса с сервера на клиент в свой набор данных (dataset). Это называется fetch - фетч. Обычно для начала выбирается только одна запись. 6. Клиентская сторона выбирает в свой набор данных (dataset) столько записей, сколько ей нужно. 7. Транзакция закрывается согласно приказу клиентской библиотеки - обратите внимание, что это приказ может не совпадать с желаниями пользователя - см. ниже. 8. Если dataset не поддерживает кэширование, то после закрытия транзакции он закрывается. Практика в БДЕ: 1) БДЕ скрывает механизм транзакций - поэтому происходит AutoCommit после запроса 2) БДЕ неявно использует не чистый "commit", а CommitRetaining - то есть транзакция подтверждается, но ее контекст не закрывается - и поэтому данные запроса после auticommit все равно видны. 3) БДЕ применяет (причем очень хорошо!) навигационный подход к возвращаемому набору данных, имитируя у него возможность движения вперед и назад (DataSet.Previous; DataSet.Next), а также более-менее корректно возвращаетчсило записей через RecordCount - для этого SQLLink-драйвер INTERBASE вынимает на клиента все записи. Таким образом, БДЕ заточена на то, чтобы выбрать все рез-ты запроса на клиента и предоставить по нему очень быструю навигацию. На нативных библиотеках ситуация другая: 1) Надо явно запускать транзакцию. Если стоит режим autocommit, то транзакция запустится сама, но в плане закрытия у нее ДРУГОЕ поведение - не как у БДЕ - см ниже. 2) До п.5 ситуация похожа и в БДЕ, и нативных библиотеках. Но после - сильные раличия. Во-первых, нативные библиотеки НЕ ЗАТОЧЕНЫ под выемку большого кол-ва данных - они берут только первую запись и ждут. Вызов DataSet.RecordCount всегда возвращает только текущее количество записей в датасете - а оно сразу после открытия действительно равно 1. 3) Нативные библиотеки рассчитаны на сервер-ориентированный подход и не слишком хорошо поддерживают работу с большими наборами данных - во всяком случае, хуже БДЕ. Сама идеология сервер-ориентированного подхода отрицает необходимость выемки на клиента многих (100-10000-...) записей. Ведь эти записи в любом случае не поместятся на экране и физиологически не смогут быть пронализированы пользователем! А если пользователь захочет еще порцию - надо перевыполнить запрос с новыми границами или условиями. 4) Нативные библиотеки используют Commit, а не CommitRetaining, поэтому при закрытии транзакции (например, в режиме AutoCommit) DataSet закрывается! Чтобы избежать этого, транзакцию надо либо явно закрывать ПОСЛЕ проведения всех операций над полученными данными, либо использовать механизмы Cashed Updates. Выводы: При использовании native библиотек доступа подсчитывать число записей в результате запроса и двигаться по результатам запроса нецелесообразно - лучше использовать отдельный запрос с SELECT Count(*)... и уточнение условий запроса. C уважением Алексей Ковязин ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2003, 10:25 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Огромное спасибо Алексею Ковязину за столь исчерпывающий ответ. Я действительно только-только переезжаю с BDE и еще не во все "въехал" :) У меня включено кэширование, AutoCommit, ... в общем все по максимуму - Auto... Не все-таки придется немного ручками поправить. >Сама идеология сервер-ориентированного подхода отрицает необходимость >выемки на клиента многих (100-10000-...) записей. Ведь эти записи в любом >случае не поместятся на экране и физиологически не смогут быть >пронализированы пользователем! А если пользователь захочет еще порцию - >надо перевыполнить запрос с новыми границами или условиями. Вопрос такой возник: У пользователя на экране в табличке показан прайс (примерно 40000 наименований). Пользователю надо из этой таблички что-нибудь выбирать (т.е. курсором, потом Enter нажать и т.п.). Как в таком случае запрашивать с сервера НЕ ВСЕ ЗАПИСИ ИЗ ЭТОЙ ТАБЛИЧКИ, а только те, которые нужно на экране показать??? Спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2003, 13:36 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Привет! Код: plaintext 1. 2. 3. 4. 5. Вот именно про такой случай я и писал. Если загружать все 4000 на клиента путем DataSet.Open, DataSet.Last, то BDE будет вне конкуренции - очень быстро. А для native библиотек подход примерно такой. - Пользователь 4000 записей сразу просмотреть не может, так? - Поэтому надо выводить меньше записей. - Чтобы выводить меньше записей, надо уточнить условия. Уточнение условий может быть двух видов - либо уточнение предметных условий, либо псевдо-уточнение - просто ограничение вывода. Уточнение предментых условий. Этот вариант является истинно SQL-евским, но пользователи, привыкшие к огромным листам EXCel, его плохо переносят (но переучивание возможно :). Когда пользователь ищет какой-то товар, надо попросить его сначала ввести первые буквы наименования, категорию товара, или ограничение по цене или еще что-то в этом роде, и потом выполнить запрос вида: Код: plaintext 1. 2. при этом выйдет гораздо меньшее число записей. Псевдоуточнение Это вебовский прием, который можно увидеть на любом сайте, где производится поиск. Мы создаем запрос как нам будет угодно (в том числе можно использовать и первый способ, с предметными условиями), и затем добавляем туда следующую вещь: 1) Либо конструкцию SELECT FIRST <x> SKIP <y> .... для вывода первых x записей после пропуска y. (Это в Firebird, в IB конструкция выглядит как ROWS x TO y в самом конце запроса) 2) Либо, если у нас нет никакой сортировки при выборе, то можно воспользоваться первичным ключом и добавить в WHERE такое условие: Код: plaintext 1. 2. 3. 4. В том и другом случае мы получим ограниченный набор записей в 100 штук (ну или сколько душа пожелает). Разумеется, эти x и y должны быть параметрами в запросе. Далее, у пользователя появляется две кнопки Страница вперед и Страница назад , после нажатия на которые параметры запроса увеличиваются/уменьшаются на заданный шаг. Также можно выполнить еще запрос с Count(), посчитать общее количество записей и вывести их для справки. Как Вы уже поняли, лучше всего будет скомбинировать оба способа сразу - и вводить хоть какие-то предметные условия, и разбивать вывод постранично. Недостатки способа: 1) Нельзя воспользоваться multi-select в grid. Это так, поэтому выбор товаров придется сдеать в стиле "корзины", когда кнопка Добавить переносит выбранный товар в другой ДатаСет. 2) Пользователь может захотеть "гладкий скроллинг", без всяких кнопок. В сущности, можно сделать отслеживание положения курсора в гриде и вызывать нужный запрос при приближении к концу, но не стоит - лучше убедить пользователя в целесообразности поэтапного вывода. Кроме того - см. достоинство N.3 3) Больше кодирования. Да, хорошо было в БДЕ - бросил грид, написал Table.open и все заработало... Но надо четко понять, что таким способом написать приложение для большого массива данных нельзя. По воробьям и слонам стреляют из разных ружей. Достоинства: 1) Очень быстрая работа и малая нагрузка сервера. Если есть все нужные индексы, то запрос на выборку выполняется моментом, а сервер при этом почти не загружен. 2) Масштабируемость. Такой подход будет работать и на 4000 записей, и на 4000000. Разница будет незаметна. 3) Легкий переход на веб-решение. Если вдруг начальство захочет выводить прайс лист на веб-сайте с возможностью поиска, то те же самые запросы и механизмы можно будет легко прикрутить к веб-решению. 4) Все правильные пацаны делают так ))) С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2003, 12:04 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Привет Алексей! Спасибо за подробности. Пойду убеждать пользователя, что весь прайс на экране ему ни к чему :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2003, 09:17 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
2 Ковязин Спасибо, листание - вот чего оказывается нехватало моим программам :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2003, 09:25 |
|
||
|
IBPlus - неверно определяет количество записей
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. Просто ты, наверное, не писал книжный каталог на 300000 библиографических карточек :) WBR, Alexey ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2003, 16:52 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32163973&tid=1580478]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
151ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 212ms |
| total: | 452ms |

| 0 / 0 |
