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

Вниз

Один DataSet - два курсора   Найти похожие ветки 

 
-=GUEST=-   (2003-10-21 17:27) [0]

Давно мучает одна проблема.
Допустим есть грид, подключенный к DataSet"у.
На этой же форме есть DBLookupComboBox, который ведет выборку по аналогичному Dataset"у.
Приходится создавать два одинаковых DataSet(Выполнять один и тот же запрос дважды)
Есть ли возможность сделать один Dataset, а навигация по нему осуществляется разными курсорами - независимо в Гриде и LookupComboBox


 
TP   (2003-10-21 17:31) [1]

Нет


 
Vlad   (2003-10-21 17:33) [2]

Можно.
Используй TClientDataSet


 
-=GUEST=-   (2003-10-21 17:37) [3]

По поводу TClientDataset - поподробнее, plz.


 
Vlad   (2003-10-21 17:45) [4]

А чего тут подробнее то ?
У тебя задача, не делать дважды один и тот же запрос к серверу.
Так делай его один раз. Результат из Query помещаешь в ClientDataSet, и имеешь два независимых но одинаковых набора данных.


 
-=GUEST=-   (2003-10-21 17:51) [5]

Имеется в виду Midas.
Если не сложно пример или ссылку(идея понятна, кроме "Результат из Query помещаешь в ClientDataSet" - не работал еще с ClientDataSet)
Заранее благодарен.


 
TP   (2003-10-21 17:54) [6]

Что в лоб, что полбу:
TQuery и TClientDateSet потомки TDataSet,а как извесно 1+1=2.


 
-=GUEST=-   (2003-10-21 17:59) [7]

При чем тут кто кого потомки?
Если кому-то будет интересно,
пример в Delphi\Demos\Midas\Aggregate


 
Vlad   (2003-10-21 18:00) [8]

-=GUEST=- (21.10.03 17:51) [5]
Лень справку открыть ?

>TP (21.10.03 17:54) [6]
Причем тут это ?


 
-=GUEST=-   (2003-10-21 18:09) [9]

"Лень - это способ отдыхать заранее.", она же двигатель прогресса.
Остался совсем простой вопрос - закачиваюся данные в ClientDataSet по-необходимости или все сразу.


 
MsGuns   (2003-10-21 18:10) [10]

Для парадокса лучший выход в данной ситуации - Vlad © (21.10.03 17:33) [2] - не создаются доп. файлы типа _sqxxxx плюс много чего хорошего у CDS. Если кол-во записей справочника небольшое, то я вообще бы отказался от DBLookUpComboBox, заменив его на модальную форму с гридом, отображающим этот CDS. Плюсов море - начиная с того, что видно все поля таблицы и заканчивая тем, что можно делать любые поиски, фильтры, правки "на лету" и т.д., т.е. имеем богатый ноабор методов полнофункционального датасета вместа кастрированного лукапкомбобокса.


 
Vlad   (2003-10-21 18:19) [11]

MsGuns © (21.10.03 18:10) [10]
вместа кастрированного лукапкомбобокса

:)))
Ну уж эт ты загнул.
Многофункциональные компоненты тоже имеют свои минусы :)


 
-=GUEST=-   (2003-10-21 18:37) [12]

Может я что-то не правильно делаю, но происходит следующее.

Лежит Query+DataSource+Grid
и Provider+ClientDataSet+DataSource+Grid

Если делаю ClientDataSet.Active := True
Открывается и то и другое, и курсок одинаковый - при переходе в одном гриде в другом тоже перемещаюсь.

Если сделать Query.Active := True, а потом ClientDataSet.Active := True, то Query самопроизвольно закрывается, но после повторного открытия работает как надо, два разных курсора - но и запрос открывается дважды.

Если есть кто добрый, рабочий пример - шо к чему.


 
-=GUEST=-   (2003-10-21 18:44) [13]

Такое впечатление, что ClientDataSet при своем открытии открывает Query, скачивает из него все данные(видно по подключенному к Query гриду), а потом закрывает его.
Не совсем то чего хотелось бы.


 
MsGuns   (2003-10-21 20:21) [14]

>Vlad © (21.10.03 18:19) [11]
>Ну уж эт ты загнул.

Ничего я не загнул. Так и есть.

>Многофункциональные компоненты тоже имеют свои минусы :)

Конечно, вертолетом сложнее управлять чем самокатом.


 
AlexGreG   (2003-10-22 08:42) [15]

А мне про лень понравилась шутка :)))


 
TP   (2003-10-22 09:05) [16]

> -=GUEST=- (21.10.03 18:37) [12]
Не очень понятно, что происходит.
Я клонирую TDataSet так:

function GetData(ADataSet: TDataSet): OleVariant;
begin
with TDatasetProvider.Create(nil) do
try
Dataset:= ADataset;
Result:= Data;
finally
Free;
end;
end;

procedure TForm1.Button1Click(Sender:TObject);
begin ClientDataset1.Data;= GetData(ADODataset1); end;

Конечно к этому времени ADODataset.Active:= True
После этого ADODataset можешь Close, можешь Free. По барабану.
Получена копия, с которой можешь делать, что хочешь.


 
-=GUEST=-   (2003-10-22 10:52) [17]

>TP (22.10.03 09:05) [16]
Спасибо, работает.
Единственный недостаток - ClientDataSet фэтчик все данные из DataSet"a, а не загружает по необходимости. На больших запросах, наверное, лучше все таки изпользовать два аналогичных Query.


 
TP   (2003-10-22 11:12) [18]

Это не недостаток. Это принцип работа TDataSet.
Нет запроса нет данных.
Что бы в TClienDataset обновились данные, необходимо закрыть
TDataset, снова открыть и повторить клонирование.
Можно обойтись и без TClienDataset.
Например так:

function TDM.Clone(DS: TADODataSet): TADODataSet;
begin
if not DS.Active then DS.Open;
Result:= TADODataSet.Create(Self);
with Result do begin
CommandText:= DS.CommandText;
Connection:= DS.Connection;
Parameters.Assign(DS.Parameters);
Open;
end;
end;

А лучше не заниматься ерундой. Измени логику программы, что бы
не было проблемы "Один DataSet - два курсора"


 
Nikolay M.   (2003-10-22 11:23) [19]

Да брось тогда ты этот DBLCB. Возьми простой DBComboBox и заполни его Items-ы руками - просто и сурово :)


 
-=GUEST=-   (2003-10-22 12:05) [20]

>Nikolay M. © (22.10.03 11:23) [19]
В идеале должно было бы:
1. Загрузка позиций по запросу, а не все сразу (допустим там пару тыся записей с картинками)
2. Раздельная навигация.

ClientDataSet - не решает первого. Т.е. качает все сразу.

>TP (22.10.03 11:12) [18]
... не заниматься ерундой. Измени логику программы ...
Есть множество задач в кот. удобно иметь два одинаковых DataSet"a
И удобно не с точки зрения программиста, а для работы пользователя - к удобству которого в конечном итоге и стоит стремится.

Решение проблемы на мой взгляд выглядит так.
Есть какой-то объект, допустим "TSuperQuery" - осущ. непосредстненную работу с базой данных.
К нему подключ. "TSuperDataSet"+DataSource+TDBGrid(или любой виз. комп.).
TSuperDataSet - осуществляет навигацию по TSuperQuery и имеет свой курсор. Если для TSuperDataSet нужны данные, кот. нет в TQuery - он их фэтчит, причем если эти же данные запросит другой TSuperDataSet - повторного фэтча не будет.
Такой херни наверно нету.


 
-=GUEST=-   (2003-10-22 12:13) [21]

В ClientDataSet есть ф-ция CloneCursor, кот. позволяет шарить одни данные между двумя(и более) ClientDataSet. Если еще решить проблему с фэтчем по запросу.
Опять таки в ClientDataSet есть с-во FetchOnDemand - но оно желаемого результата не дает.


 
TP   (2003-10-22 12:23) [22]

Метод CloneCursor TClientDataSet не создаёт второй курсор.
Он создаёт копию "родителя".(см. исходники).
Полбзователей конечно надо уважать, но зачем нужен TSuperDataSet,
я так и не понял.


 
-=GUEST=-   (2003-10-22 12:41) [23]

Может по исходникам и так, но в хелпе:
Call CloneCursor to share the data belonging to another client dataset.

Последняя проблема - возможно ли заставить ClientDataSet загружать данные по надобности

>TP (22.10.03 12:23) [22] но зачем нужен TSuperDataSet
Ну это для примера.
Можно сказать что TSuperQuery = TDataSetProvider, а TSuperDataSet = TClientDataSet
Но чтобы Sharing Data - а не создание копии(а Вы говорите это происходит по исходникам), и Fetch-On-Demand для этого самого Shared Data.


 
TP   (2003-10-22 13:29) [24]

У TDataSetProvider.Option есть значение poAutoRefres.
В D5 это неработает однозначно, в D6,7 не знаю, ещё не пробовал.
Так что проблему автоматического обновления запроса я решал при помощи COM-ика с событием, которое при изменении данных на сервере срабатывало у клиентов.
Но это всё делалось при помощи MIDAS.


 
Nikolay M.   (2003-10-22 13:52) [25]


> -=GUEST=- (22.10.03 12:05) [20]
> >Nikolay M. © (22.10.03 11:23) [19]
> В идеале должно было бы:
> 1. Загрузка позиций по запросу, а не все сразу (допустим
> там пару тыся записей с картинками)
> 2. Раздельная навигация.

А как по-твоему, в DBLCB тогда появятся ВСЕ записи, если не фетчить их все? Сделай тогда вспомогательный запрос, в котором будет селект одного нужного поля и пихай его в DB(Lookup)ComboBox.


 
-=GUEST=-   (2003-10-22 14:13) [26]

>Nikolay M. © (22.10.03 13:52) [25]
По поводу DBLookupComboBox утверждать не буду, но вот грид загружает записи по необходимости, да и LookupComboBox должен делать точно также. А то выходит ты раскрываешь его и тут фэтчится в примеру 400 000 записей - не логично как-то.

Вспомогательный запрос я постоянно и использую. Но как написано в теме топика - "Давно мучает одна проблема" - зачем выполнять два разных запроса, загружать одну и туже информацию (даже если фетчатся только необходимые записи - выходит ~трафик*2, а если будет Paradox то и поболее) если можно найти способ "клонирования" курсора. ClientDataSet практически решает эту проблему.


 
TP   (2003-10-22 14:18) [27]

TDBGrid ни когда не загружал записи. Во все времена записи грузились в TDataSet и его потомков. TDBGrid только отображает записи из TDataSet.По крайней мере так было до сегодняшнего дня.


 
Nikolay M.   (2003-10-22 14:26) [28]


> грид загружает записи по необходимости

Данные загружает DataSet, плюс фетчить все или по частям - зависит от используемых компонент.

А то, что есть необходимость фетчить 400 000 записей - неправильно идеологически. Ты что, хочешь довести до инфаркта юзера, предложив ему список в почти поллимона записей?


 
-=GUEST=-   (2003-10-22 14:39) [29]

>TP (22.10.03 14:18) [27]
Мы же не в детском саду. Если Вы подключите TDBGrid к TQuery, то он будет грузить столько записей, сколько потребует TDBGrid для отображения. Т.е. если опустить детали грузит записи все-таки грид, точнее "требует" их у набора данных
А по поводу кто кого потомок Вы объясняли еще в начале топика.

ПРОБЛЕМА заставить ClientDataSet загружать записи по запросу от грида. Или какое-то подобное решение.


 
TP   (2003-10-22 14:49) [30]

Похоже мы в детском саду: TQuery грузит столько записей, сколько записей в базе удолетворяет условиям запроса. А TDBGrid отображает столько записей, сколько записей уместится в высоте TDBGrid.


 
Vlad   (2003-10-22 14:51) [31]

>TP (22.10.03 14:49) [30]
TQuery грузит столько записей сколько настроено в БДЕ алиасе или столько сколько отфетчит юзер.


 
-=GUEST=-   (2003-10-22 15:08) [32]

В любой умной книжке описана разница между TQuery и TTable и все её знают.
Не важно как грузит TQuery(TQuery для примера взято - что бы указать что используется не TTable, для IB вообще FIBPLus используется - тут будет меньше споров кто как фетчит ).
Это детали. В другом проблема.



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

Форум: "Базы";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.024 c
3-40849
DolginD
2003-10-19 22:22
2003.11.13
install Shield и BDE


14-41934
Knight
2003-10-19 19:50
2003.11.13
Нужен рисунок странника или путкника...


11-41118
gori
2003-02-20 03:28
2003.11.13
Убрать автосоздание второго окна


14-42082
BAPBAP
2003-10-22 18:15
2003.11.13
Почтовик и прокси


14-42127
Nikolay M.
2003-10-22 13:08
2003.11.13
Вот не повезло с отчеством...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский