Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Метод FindKey и TQuery, помогите найти аналог 
:(
    Опции темы
Serggggg
  Дата 11.2.2004, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.12.2003
Где: Донецк, Украина

Репутация: нет
Всего: нет



Всем привет!
Прошу совета. Проблема не очень сущетвенная, но желательно разобраться.
Как мы все знаем, у компонента TTable есть такой чудный метод, как FindKey, который после Refresh'а позволяет вернуться к нужной записи. В моем случае используется TQuery. Вышеупомянутого метода для него нет. Запрос "обновляется" посредством операций
Active:=False;
Active:=True;
Курсор (естественно) скачет сразу на первую запись. А как мне перевести его на ту позицию (скажем, Grid'a), с которой перед обновлением запроса производилось, например, удаление записи?
--------------------
C уважением, Serggggg.
PM MAIL ICQ   Вверх
x77
Дата 11.2.2004, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 1
Всего: 22



используя Locate по ключевому полю. в принципе, можно по любому, но Locate использует при поиске индексы, поэтому желательно, чтобы поле было как минимум индексированным, а лучше - ключевым.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Kesh
Дата 11.2.2004, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

Репутация: 3
Всего: 54



Имхо, для квери это не самый лучший способ...
Представь, что у тебя клиент, подсоединенный к табличке в базе, в которой записей эдак около миллиона, да еще плюсом есть какое-нить поле типа BLOB/CLOB/BFile. В Oracle при реализации такой квери ты получишь где-то N первых записей, остальные будут подгружаться по мере необходимости. А теперь представь, что ты своим FindKey обращаешься к одной из последних записей в квере... Придется пролистывать всю кверю, плюс тянуть LOB-поля, и все это по сети, а если в BLOB'e еще и картинка, еще и BMP'шная... Представь себе загрузку сети...
А если у тебя при этом еще и несколько клиентов...

P.S. Все это конечно же ИМХО...


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
Maverick
Дата 11.2.2004, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1307
Регистрация: 22.9.2003
Где: Odessa, Ukraine

Репутация: нет
Всего: 10



А не лучше перед удалением запомнить номер строки, на которой стоишь... а после обновления - направиться к этому номеру... Разве порядок-нумерация строк изменится? По-моему просто сдвинется на одну запись... Значит, попадешь достаточно близко... Или сам запрос в Query меняется?


--------------------
smile
PM ICQ GTalk   Вверх
x77
Дата 11.2.2004, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 1
Всего: 22



kesh, при описанной тобой ситуации, нужная запись получается отдельным запросом. ну а для всех прочих случаев... есть же, в конце концов, стандартные решения, зачем сразу в крайности?


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 11.2.2004, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 1
Всего: 22



Maverick, о том и речь. делаем DisableControls, запись удаляется, курсор сдвигается на строку, запоминается значения ключевого поля (полей), выключается/включается квери, курсор позиционируется на место методом Locate, делаем EnableControls.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Maverick
Дата 11.2.2004, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1307
Регистрация: 22.9.2003
Где: Odessa, Ukraine

Репутация: нет
Всего: 10



Вы меня не поняли.... x77.... Зачем Locate.... Запомнить надо RecNo... Потом вернуться к нему же.... или RecNo+1....
Зачем искать?.... Заранее запомнить...


--------------------
smile
PM ICQ GTalk   Вверх
x77
Дата 11.2.2004, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 1
Всего: 22



Maverick, насколько я знаю, RecNo имеет смысл только для локальных баз (dBase, Paradox, etc.) для Interbase или Oracle RecNo равен -1 или вообще какой-нибудь чепухе.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Serggggg
Дата 11.2.2004, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.12.2003
Где: Донецк, Украина

Репутация: нет
Всего: нет



Значение ключевого поля - это замечательно. Я и сам сторонник поски по ключу. Но в инспекторе объектов IndexName или IndexFieldName задаётся только для таблиц, а не для запросов. Для компонента TQuery такого свойства там не описано.
x77, база действительно на Oracle.
--------------------
C уважением, Serggggg.
PM MAIL ICQ   Вверх
Kesh
Дата 11.2.2004, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

Репутация: 3
Всего: 54



И все же для квери запоминать какой-то номер мне кажется не есть гуд...
Ибо для реляционых баз данных, в силу определения, нет понятия первая, предыдущая, последующая, последняя запись... Важно только условие выборки...


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
Maverick
Дата 11.2.2004, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1307
Регистрация: 22.9.2003
Где: Odessa, Ukraine

Репутация: нет
Всего: 10



x77.... Ты прав.... Пробую под Informix - =-1.... Буду знать....


--------------------
smile
PM ICQ GTalk   Вверх
Петрович
Дата 12.2.2004, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата
А не лучше перед удалением запомнить номер строки, на которой стоишь... а после обновления - направиться к этому номеру... Разве порядок-нумерация строк изменится? По-моему просто сдвинется на одну запись... Значит, попадешь достаточно близко...


Для реляционных БД понятия "номер строки" - несуществует. Даже в локальных БД (dBase, Paradox, и п.р.) в которых действителен RecNo, такой метод не годится! Поскольку во первых, помимо тебя, в таблице могут копошиться и другие юзеры которые могут вставлять/удалять записи. И во вторых, возможны запросы манипулирующие неопределенным числом записей, например DELETE FROM TABLE Vasya WHERE Price > 100

Правильным способом будет использовать Locate. Если есть primary key, то использовать его, если нет, то можно использовать все поля.

Например можно описать такой объект:
Код
type
 tSaveContext = class
   private
     fds          :TDataSet;
     FieldsList   :String;           // Список полей DataSet'а
     FieldsValues :array of Variant; // Список значений текущей записи
   public
     constructor Create (ads :TDataSet);
     destructor Destroy; override;
   end;

constructor tSaveContext.Create (ads :TDataSet);
var i :Integer;
begin
 inherited Create;

 if  not Assigned(ads)  then  Exit;
 if  not ads.Active     then  Exit;

 fds := ads;

 // сохранить список имен и значений полей текущей записи
 FieldsList := '';
 with  fds  do begin
   SetLength(FieldsValues,Fields.Count);
   for i:=0  to  Fields.Count-1  do with  Fields[i]  do begin
     FieldsList      := FieldsList + FieldName + ';';
     FieldsValues[i] := Value;
   end;
 end;
 Delete(FieldsList,Length(FieldsList),1);
end;

destructor tSaveContext.Destroy;
begin
 if  Assigned(fds)  and  fds.Active  and  (Length(FieldsList) = 0)  then begin
   try
     fds.Locate(FieldsList,FieldsValues,[]);
     fds := nil;
     FieldsList   := '';
     SetLength(FieldsValues,0);
   except
     // Ошибки в данном случае не повод для беспокойства, просто не восстановится
     // позиция в датасете
   end;
 end;

 inherited;
end;


А потом его использховать, например так:
Код
procedure Refresh(ads :tDataSet);
begin
 with  tSaveContext.Create(ads)  do try
   ads.Close; // или ads.Active := False;
   ads.Open;  // или ads.Active := True;
 finally
   Free;
 end;
end;



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Serggggg
Дата 12.2.2004, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.12.2003
Где: Донецк, Украина

Репутация: нет
Всего: нет



Благодарю за совет. Стоит попробовать!
--------------------
C уважением, Serggggg.
PM MAIL ICQ   Вверх
Maverick
Дата 12.2.2004, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1307
Регистрация: 22.9.2003
Где: Odessa, Ukraine

Репутация: нет
Всего: 10



[QUOTE]Для реляционных БД понятия "номер строки" - несуществует. Даже в локальных БД (dBase, Paradox, и п.р.) в которых действителен RecNo, такой метод не годится! Поскольку во первых, помимо тебя, в таблице могут копошиться и другие юзеры которые могут вставлять/удалять записи. И во вторых, возможны запросы манипулирующие неопределенным числом записей, например DELETE FROM TABLE Vasya WHERE Price > 100[/QUOT]

Последнее время были задания для DBF для работы одного пользователя.... в стиле с навигатором ДОБАВИТЬ/УДАЛИТЬ.... Вот и дошел до ручки....


--------------------
smile
PM ICQ GTalk   Вверх
cvi
Дата 13.2.2004, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 10.9.2003
Где: Украина, Киев

Репутация: нет
Всего: нет



Вижу моего решения еще нет.
Пишу так

var
Save_Place : TBookMark;

Save_Place := Query.(Что то типа)SaveBookMark;(точно не помню как называется)
Query.Actice := False;
Query.Active := True;
Query.GotoBookMark(Save_Place);
Query.FreeBookMark(Save_Place);

точно работает по Interbase, paradox

Спасибо за внимание. smile.gif)
PM MAIL WWW ICQ   Вверх
Medved
Дата 13.2.2004, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 7209
Регистрация: 15.9.2002
Где: Kazakhstan, Astan a

Репутация: 1
Всего: 154



Цитата
Save_Place := Query.(Что то типа)SaveBookMark;(точно не помню как называется)

Этот метод называется GetBookmark.

Но учтите, вот из F1:
GetBookmark relies on a protected method to obtain the bookmark value. TDataSet descendants implement this method to provide their own type of bookmark support. Unidirectional datasets do not support bookmarks, and so do not return a meaningful value.

Иначе говоря, GetBookmark не будет работать на однонаправленных наборах данных (т.е. не подлежащих редактированию, кэшированию, фильтрации и индексированию, а также навигации. Такой набор данных напрмер возвращает dbExpress).


--------------------
http://extreme.sport-express.ru/
...и неважно сколько падал, важно сколько ты вставал...
PM MAIL WWW ICQ Skype GTalk   Вверх
Петрович
Дата 13.2.2004, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата
Save_Place := Query.(Что то типа)SaveBookMark;(точно не помню как называется)
Query.Actice := False;
Query.Active := True;
Query.GotoBookMark(Save_Place);


Тогда-уж проще:

Код
...
var
 SavedBookmark :String;
...
 SavedBookmark := Query.Bookmark;
 Query.Actice := False;
 Query.Active := True;
 Query.Bookmark := SavedBookmark;
...


Однако не стал рекомендовать, поскольку где-то читал что закладка (Bookmark) сохраненная до закрытия датасета может стать недействительной после его открытия. Причем сам когда-то "обжегся" (Interbase через IBX), теперь использую закладки только когда в промежутке не надо закрывать датасет.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Medved
Дата 13.2.2004, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 7209
Регистрация: 15.9.2002
Где: Kazakhstan, Astan a

Репутация: 1
Всего: 154



Цитата

Однако не стал рекомендовать, поскольку где-то читал что закладка (Bookmark) сохраненная до закрытия датасета может стать недействительной после его открытия. Причем сам когда-то "обжегся" (Interbase через IBX), теперь использую закладки только когда в промежутке не надо закрывать датасет.


Полностью согласен, пользоваться закладками надо с осторожностью.


--------------------
http://extreme.sport-express.ru/
...и неважно сколько падал, важно сколько ты вставал...
PM MAIL WWW ICQ Skype GTalk   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1045 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.