Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.12.06;
Скачать: [xml.tar.bz2];

Вниз

технология ADO и RecordCount   Найти похожие ветки 

 
Delphi2020   (2009-10-20 19:51) [0]

Уважаемые мастера, такой вот у меня созрел вопрос:
Где-то слышал, что использование технологии BDE может привести к тому, что свойство RecordCount (например в Query) покажет неправильный результат, т.к. не все строчки считаются.
Так вот, вопрос – подвержен ли ADOQuery такому-же глюку?
PS: ни в Query, ни в ADOQuery поймать этот глюк так и не получилось.


 
Kolan ©   (2009-10-20 19:54) [1]

Это не неправильный результат и не глюк. Это корректное поведение, прочтите справку.


 
Delphi2020   (2009-10-20 20:06) [2]

Kolan ©, Спасибо. Действительно, в справке по ADOQuery написано:

> The number of rows indicated might be less than the total
> number of rows in a table.

Как же тогда узнать, сколько строк содержится в выборке?
И еще - есть ли способ узнать - пустая выборка или не пустая (или в этом случае if RecordCount=0 и if RecordCount<>0 подойдет)?


 
Anatoly Podgoretsky ©   (2009-10-20 20:07) [3]

> Delphi2020  (20.10.2009 19:51:00)  [0]

А зачем сравнивать технологию и отдельный компонент.
Кроме того RecordCount  всегда покажет правильный результат, только он тебе может не понравится.


 
Delphi2020   (2009-10-20 20:09) [4]

Anatoly Podgoretsky © да, это я уже понял - показывается число строк в датасете. Но мне нужно число строк в выборке, ну и иметь возможность определять - пустая ли выборка вернулась.


 
Delphi2020   (2009-10-20 20:15) [5]

Кстати, сколько не пользуюсь ADOQuery, такой особенности RecordCount не замечал... Может быть не выводятся только какие-нибудь служебные записи, и дело не в нехватке памяти? Или наоборот - есть какой-то порог числа записей в датасете, и все, что за ним, не считывается?


 
qwer_qwer   (2009-10-20 20:16) [6]


> Но мне нужно число строк в выборке, ну и иметь возможность
> определять - пустая ли выборка вернулась.


Так кто ж мешает?
RecordCount вернёт тебе правильное значение или -1. Всего лишь.
Если выборка короткая, то просто используй для гарантии дополнительный запрос SELECT COUNT().


 
Anatoly Podgoretsky ©   (2009-10-20 20:19) [7]

> Delphi2020  (20.10.2009 20:09:04)  [4]

Не нужно это тебе, при наличии одноименной с задачей функцией.


 
Delphi2020   (2009-10-20 20:20) [8]


> RecordCount вернёт тебе правильное значение или -1.

Спасибо, это выриант. После каждого open буду проверять if RecordCount=-1 then MessageBox("Ошибка").


> Если выборка короткая, то просто используй для гарантии
> дополнительный запрос SELECT COUNT().

Увы, выборки обычно тяжелые. Кроме того, если как-то не встраивать count в основной запрос, может возникнуть такой вариант, когда второй пользователь введет еще строку и count окажется больше на единицу...


 
qwer_qwer   (2009-10-20 20:21) [9]


> да, это я уже понял - показывается число строк в датасете.
>  Но мне нужно число строк в выборке,


Они совпадают.


 
Delphi2020   (2009-10-20 20:22) [10]

Не нужно это тебе, при наличии одноименной с задачей функцией.
А Open  всегда возвращает действительное число строк в выборке???


 
qwer_qwer   (2009-10-20 20:23) [11]


> После каждого open буду проверять if RecordCount=-1 then
> MessageBox("Ошибка").


Для проверки есть свойство isEmpty.


 
qwer_qwer   (2009-10-20 20:24) [12]

Какая хоть СУБД?


 
Delphi2020   (2009-10-20 20:25) [13]

База SQL 2005.
Думаю, что если RecordCount<>Тому, что действительно должно было вернуться по запросу, то это уже можно расценивать как ошибку и сообщать пользователю.


 
Delphi2020   (2009-10-20 20:28) [14]

Т.е. if RecordCount=-1 then
begin
 Mesag...
 Abort
end;

Иначе через next, как я понимаю, пройдут только RecordCount строк или еще где ошибка вылезет.


 
qwer_qwer   (2009-10-20 20:48) [15]

Так я не пойму, в чём у тебя вопрос.
RecordCount=-1 у меня не возникало такого.
RecordCount возвращает праавильное значение количества записей, которые вернула СУБД по запросу.


 
qwer_qwer   (2009-10-20 20:49) [16]

Может кто подскажет тогда - в каком случае RecordCount вернёт неверное значение? Я с таким не сталкивался и не встречал разъяснений.


 
palva ©   (2009-10-20 21:37) [17]

qwer_qwer   (20.10.09 20:49) [16]

Ну вот я попробовал. SQL Server 2005 Express
ADODataSet1 имеет:
ConnectionString Provider=SQLNCLI;Server=.\SQLEXPRESS;Trusted_Connection=yes;
CommandText select * from ...
CursorLocation clUseServer
CursorType ctDynamic
По клику кнопки выполняется:
 ADODataSet1.Open;
 ShowMessage(IntToStr(ADODataSet1.RecordCount));
 ShowMessage(IntToStr(ADODataSet1.Fields[0].AsInteger));

Сначала показывает -1
потом значение первого поля первой записи.

А какие могут быть разъяснения? Так работает и всё. Сервер не знает сколько записей на самом деле будет прочитано из датасета и дает только первые записи, по мере их чтения происходит подкачка дополнительных записей. А сколько записей всего сервер даже и не знает. Кроме того, их количество может меняться по мере чтения датасета.


 
Плохиш ©   (2009-10-20 23:08) [18]


> Delphi2020   (20.10.09 20:20) [8]
>
>
> > RecordCount вернёт тебе правильное значение или -1.
>
> Спасибо, это выриант. После каждого open буду проверять
> if RecordCount=-1 then MessageBox("Ошибка").

Странно, у меня всегда он равен -1 и это не ошибка.
А пустой набор данных это, когда, сразу после открытия, eof = true.


 
Игорь Шевченко ©   (2009-10-20 23:26) [19]


> А пустой набор данных это, когда, сразу после открытия,
> eof = true


пустой набор - это когда IsEmpty = true ;)


 
palva ©   (2009-10-20 23:46) [20]


> пустой набор - это когда IsEmpty = true ;)

А я привык для этого проверять EOF сразу после открытия. Поскольку isEmpty в чистом ADO нет. Наверняка делается что-то в роде IsEmpty := EOF AND BOF


 
qwer_qwer   (2009-10-21 00:52) [21]


> Плохиш ©   (20.10.09 23:08) [18]
> Странно, у меня всегда он равен -1
> и это не ошибка.А пустой набор данных это, когда, сразу
> после открытия, eof = true.


У меня TADOQuery возвращает нормальное значение почему-то...


 
qwer_qwer   (2009-10-21 00:53) [22]

PS.
СУБД MSSQL SERVER 2005.
Запрос простой - select * from MyTable


 
Германн ©   (2009-10-21 01:06) [23]


> qwer_qwer   (21.10.09 00:52) [21]
>
>
> > Плохиш ©   (20.10.09 23:08) [18]
> > Странно, у меня всегда он равен -1
> > и это не ошибка.А пустой набор данных это, когда, сразу
> > после открытия, eof = true.
>
>
> У меня TADOQuery возвращает нормальное значение почему-то.
> ..
>

Везение. И малый круг решаемых задач.


 
qwer_qwer   (2009-10-21 01:14) [24]


> Везение. И малый круг решаемых задач.


Возможно.
Просто из справки непонятно, в каком случае Should ADO not be able to determine that actual number of rows


 
qwer_qwer   (2009-10-21 01:18) [25]

А, всё понятно.

Похоже, что RecordCount не будет работат ь в единственном случае - когда
ADODataSet.CursorType=ctDynamic, потому что в этом случае RecordCount просто не имеет смысла:
ctDynamic: Dynamic cursor; data modifications, deletions, and insertions by other users are visible; scrolling forward and back allowed.


 
qwer_qwer   (2009-10-21 01:19) [26]

Во всех остальных случаях RecordCount будет работать как надо.


 
qwer_qwer   (2009-10-21 01:38) [27]

Вот более подробное описание:

ADO datasets sometimes return –1 for their RecordCount.

A forward-only cursor cannot know how many records are in the result set until it reaches the end, so it returns –1 for the RecordCount.
A static cursor always knows how many records are in the result set, because it reads the entire set when it is opened, so it returns the number of records in its result set.
A keyset cursor also knows how many records are in the result set, because it has to retrieve a fixed set of keys when the result set is opened, so it also returns a useful value for RecordCount.
A dynamic cursor does not reliably know how many records are in the result set, because it is regularly rereading the set of keys, so it returns –1. You can avoid using RecordCount altogether and execute SELECT COUNT(*) FROM tablename, but the result will be an accurate reflection of the number of records in the database table—which is not necessarily the same as the number of records in the dataset.


 
Германн ©   (2009-10-21 01:50) [28]


> qwer_qwer   (21.10.09 01:38) [27]
>
> Вот более подробное описание:
>

Это и было сказано в:

> palva ©   (20.10.09 21:37) [17]


 
Игорь Шевченко ©   (2009-10-21 01:51) [29]

Вот же напридумывали разных курсоров.

По моему (нескромному) мнению - не стоит опираться на свойство RecordCount (а тем более, выдавать SELECT COUNT(..) FROM (..) в многопользовательском режиме для того, чтобы узнать, сколько записей), потому что оно ведет к неоправданым издержкам при работе с нефайловой базой данных - довольно редко имеет смысл сразу после открытия курсора тащить весь результат на клиента.


 
Delphi2020   (2009-10-21 07:04) [30]


> пустой набор - это когда IsEmpty = true ;)

Спасибо  - вот, собственно, и ответ на мой вопрос про определения того, пустая выборка или нет.
И еще небольшой вопрос: ExecSQL возвращают полное количество строк или тоже может подойти к проблеме подсчета обработанных строк "творчески"?


 
Delphi2020   (2009-10-21 08:33) [31]

Если кто-то знает ответ на мой вопрос про ExecSQL - пожалуйста, ответьте. Может быть это просто, но после RecordCount я уже не знаю, на что из возврата ADO можно положиться. В справке, вроде бы, никаких исключений нет.

И еще один вопрос: верно ли, что если я напишу:
 
 ADOQ.SQL.Clearl
 ADOQ.SQL.Add("SELECT.......
 try
   ADOQ.SQL.Open;
 exception
   ...
 end;
 if ADOQ.RecordCount=-1 then
 Begin
   Message...
   abort;
 end;
 
То в коде после этой проверки можно будет полагаться на RecordCount как на точное кол-во строк? (именно строк в полной выборке, которую я и ожидал получить)


 
Sergey13 ©   (2009-10-21 08:52) [32]

> [31] Delphi2020   (21.10.09 08:33)
> То в коде после этой проверки можно будет полагаться на
> RecordCount как на точное кол-во строк?

А для чего тебе нужно полагаться на RecordCount? И полагать на это титанические усилия?


 
Delphi2020   (2009-10-21 09:01) [33]

Титанических усилий не будет, т.к. в моей программе все запросы выведены в отдельную функцию, внутри которой производится open. Там я и намереваюсь добавить проверка RecordCount=-1.
RecordCount нужет, т.к. иногда нужно узнать - сколько строк имеется в базе под мой запрос.


 
Sergey13 ©   (2009-10-21 09:05) [34]

> [33] Delphi2020   (21.10.09 09:01)
> сколько строк имеется в базе под мой запрос.

И что изменится если там не 34 записи, а 86 например?


 
Delphi2020   (2009-10-21 09:12) [35]

Кде-то это число может вывестись на экран пользователю. Где-то при Next не обработаются оставшееся записи (хотя последнее можно избежать, переведя циклы for в while), да и вообще, если узнавать - пустая ли база через RecordCount, можно получить -1 а не 0. Вот я и подумал, что проверка RecordCount=-1 в [31] может быть панацеей от всех этих случаев и гарантировать нормальные показания в RecordCount. И решил спросить - так это или не так.


 
Anatoly Podgoretsky ©   (2009-10-21 09:28) [36]

> Delphi2020  (21.10.2009 09:01:33)  [33]

Старались, старались, а все обсуждение пофигу.


 
Delphi2020   (2009-10-21 09:43) [37]

Ну почему же. Не пофигу. Я читаю и строю для себя выводы. Вот IsEmpty я никогда раньше не использовал. Теперь хотелось бы найти общий способ, позволяющий узнать, можно использовать RecordCount или нет. Например, если нужно изменить размеры формы, так, чтобы влезали все строки и др.

Пока буду использовать в таких целях RecordCount=-1 после Open (такое решение тоже посоветовали на этом форуме). Что касается типа курсора - для разных программ и даже запросов он может быть разный.

Всем большое спасибо.

Буду рад, если кто-нибудь еще чего посоветует.


 
Anatoly Podgoretsky ©   (2009-10-21 09:53) [38]

> Delphi2020  (21.10.2009 09:43:37)  [37]

RecordCount=-1 нормальное состояние, которое не о чем ни говорит.


 
qwer_qwer   (2009-10-21 09:54) [39]


> Германн ©   (21.10.09 01:50) [28]
>Это и было сказано в:> palva ©   (20.10.09 21:
> 37) [17]


Да неужто?


 
Delphi2020   (2009-10-21 10:06) [40]

Удалено модератором


 
Delphi2020   (2009-10-21 10:09) [41]

> RecordCount=-1 нормальное состояние, которое не о чем ни
> говорит.

Ясно. Для некоторых курсоров это просто необходимо, т.к. RecordCount узнать они не в состоянии.

Ну если оставить тип курсора по умолчанию: KyrsorType=ctKeyset то RecordCount и IsEmpty всегда будет показывать то, что надо?

Судя по этому:
> A keyset cursor also knows how many records are in the result
> set, because it has to retrieve a fixed set of keys when
> the result set is opened, so it also returns a useful value
> for RecordCount.
вроде бы да (отдельное спасибо qwer_qwer), хотя, уча английский, я с ним все еще не в ладах.


 
Delphi2020   (2009-10-21 10:51) [42]

Все. Вроде бы разобрался полностью:

После проверок получилась такая штука (1-показывает число строквсе правильно, -1 - показывает -1):

            ctDynamic   ctKeyset   ctOpenForwardOnly   ctStatic   ctUnspecified
clUseClient      1           1             1                1          1
clUseServer      0           1             0                1          0


В итоге получаются два вывода:
1. используя настройки по умолчанию (clClient и ctKeySet) RecordCount показывается правильно.
2. IsEmpty показывается правильно всегда, даже когда RecordCount=-1

Если кто-то в чем-то не согласен - дописывайте.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.12.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.006 c
15-1254978520
@!!ex
2009-10-08 09:08
2009.12.06
При покупки VDS просит ввести настройки сервера.....


15-1255012142
Leonid Troyanovsky
2009-10-08 18:29
2009.12.06
Похороните меня за плинтусом


15-1255088311
g11
2009-10-09 15:38
2009.12.06
Сведения в exe-файлах


15-1254981541
Хм...
2009-10-08 09:59
2009.12.06
Самопроизвольное движение курсора мыши


1-1227707159
DmitriyG
2008-11-26 16:45
2009.12.06
На этапе компиляции определить подключен или нет модуль





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский