![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему не правильно работает RecordCount? [D5, IB5.x, ]
Dim © (2001-12-17 11:57:00)Доброго всем здоровья.
В чем проблема, почему в InterBase"е в RecordCount неверные значения. Мне один программист говорил, что это не лечится, но что-то не очень в это верится. Подозреваю что в Borlande работают серьезные ребята, и не незаметить такую лажу просто невозможно.
Какие будут мнения.
Alexandr (2001-12-20 14:00:00) [1]кстати рассмотри такой вариант:
все данные все-равно на клиенте нужны будут поэтому Last или fetchAll все равно делать- а после этой операции RecordCount вычисляется очень быстро.
так надо-ли в таком случае еще и на сервере count делать?
Alexandr (2001-12-20 13:58:00) [2]дык это тут уже обсудили.
Не надо повторяться
Владимир Шаламберидзе (2001-12-20 12:37:00) [3]RecordCount не определен для ВСЕХ SQL запросов будб то интербаиз или оракл
Вся проблема в том что при выражении типа select * from blabla происходит чтение первых N записей и программа не знает кол-во записей
Вариант с
Query.Last; Query.Recno
хорош только для небольших таблиц так как при этом происходит чтение ВСЕЙ таблицы. Я бы порекомендовал вариант
select count(*) from blabla и тд
для больших таблиц это даст ощутимый выигрыш в скорости
Alexandr (2001-12-20 11:54:00) [4]2Desdechado: Во-во. И что значит "приблизительный" такого понятия в математической логике (да и программировании) нет (см. "женская логика").
2Slava:Вот и я о том же.
Slava (2001-12-20 11:30:00) [5]Использовал и IBX и FIBPlus:
RecordCount ни разу не обманул :)
Естественно, если его прочитать после FetchAll...
Desdechado (2001-12-20 11:02:00) [6]The count is approximate in some cases = В некоторых случаях подсчет приблизительный
Какие именно эти "некоторые" случаи - неизвестно ...
Alexandr (2001-12-20 07:36:00) [7]читал я это.
Ну и что?
Desdechado (2001-12-19 17:18:00) [8]2 Alexandr
Цитирую справку:
Use RecordCount with care, because record counting can be a costly operation, especially for SQL queries that return large result sets. Generally, an application should only use RecordCount with Paradox and dBASE tables.
This function is meant to get the number of records associated with the cursor. The count is approximate in some cases.
Alexandr (2001-12-18 12:25:00) [9]а вот так неправильно?
Query1.Last;
r:=Query1.RecordCount; // Это и есть количество записей в указаной базе
или так
Query1.FetchAll;
r:=Query1.RecordCount; // Это и есть количество записей в указаной базе
belobadgo (2001-12-18 11:49:00) [10]Была у меня когда-то такая проблемма, не решил... Но позже вычитал , что для получения коректного значения RecordCount необходимо сходить на последнюю запись, а потом вернутся на первую... Но я не проверял.
Dim (2001-12-18 11:49:00) [11]>vinni2000
Классно, а главное быстро и правильно.:)))
dimsfdf (2001-12-18 10:37:00) [12]по моему RecordCount глючит когда запрос возвращает безразмерные поля (типа Memo, Blob ...) (DB2v6,D5)
vinni2000 (2001-12-18 10:30:00) [13]С проблемой Recordcount в Interbase я разобрался так.
Query1.Last;
r:=Query1.Recno; // Это и есть количество записей в указаной базе
Alexandr (2001-12-18 09:01:00) [14]2Desdechado:Обоснуй
2Dim:Никто и не говорит, что тормозить не будет, особенно если выборка большая.А чтобы правильные значения были, FetchAll делал.
Count(*) быстрее будет чем Open+FetchAll+RecordCount
т.к. в первом случае подсчитывает сервер, пусть и не так оптимально как блокировочные сервера(Interbase версионник)
а во втором случае таблица загоняется целиком на клиента, и клиент подсчитывает количество записей.Достоиством здесь является то, что данные уже оказываются на клиенте.
Ведь попробуй после Open сделать Last - тоже тормозить будет если строк много в запросе-это данные с сервера на клиент передаются.А RecordCount после этого пройдет мгновенно...
Почему для Ttable это не так? при last Ttable не перечитывает весь запрос с сервера, а берет только конец таблицы и в случае Client-server Ttable ни в коем случае использовать не рекомендуется.
Вообщем выводы следующие.
при Clent-Server архитектуре не рекомендуется возвращать большие наборы данных- да и зачем- оператор их все равно все не прочитает. Нужно правильно формировать запрос к серверу, чтобы он возвращал только то, что нужно.
Тогда ни count(*) ни RecordCount на клиенте тормозить не будут
Dim (2001-12-18 07:28:00) [15]>kserg@ukr.net
with Query do begin
SQL.Add(select * from table);
Open;
Statusbar1.Panels.Items[1].Text := IntToStr(RecordCount);
end;(Причем этот же код в MSSQL 6.5 работает правильно)
---------------------------------------------------------------------
>asafr ©
Оно конечно так, но больно уж тормозит даже у меня на машине(300 МГц, 128Мб), а что будет у оператора (75 МГц 16Мб)
---------------------------------------------------------------------
>Alexandr ©
Попробовал поработать черех IBX. Неверные значения это, в списке 33 строки, а в Statusbar"е 22. Причем если строк не много 7,13 то все зашибись.
Desdechado (2001-12-17 20:59:00) [16]RecordCount годится только для TTable на файл-сервер, для остального - это заглушка, которая может работать самым непредсказуемым образом
Alexandr (2001-12-17 14:17:00) [17]1)не так плох FetchAll, как о нем пишут не знающие люди.
2)в FIBPlus есть возможность делать RecordCount без FetchAll- выполняя аналогичный запрос с select count(*)
Mick (2001-12-17 14:06:00) [18]Отсюда мораль: не используй RecordCount при работе с любым SQL сервером.
Самая малая неприятность которая при этом может случиться: - получите 0 или -1.
Но чаще всего получите FetchAll :(
Alexandr (2001-12-17 14:00:00) [19]RecordCount никаким образом с сервером не связан.
Он связан библиотекой доступа.
Через что ты работаешь с Interbase (BDE,FIBPlus,IBX,IBObjects или другое)?
P.S. для некоторых библиотек перед RecordCount надо писать FetchAll
некоторые библиотеки имеют 2 метода вычисления RecordCount-путем прямого пересчета всех записей на клиенте или путем вызова select count(*)
А как это неверные значения-можно подробнее...
asafr (2001-12-17 13:26:00) [20]Используй
COUNT(*)в SQL. Никаких проблем.