Как ПРАВИЛЬНО ловить курсор в табл. после передер. сервера?

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 июл 2006, 15:30

Ivan_Pisarevsky писал(а):
Марина писал(а):Т.е. теперь курсор надо поставить на 30-ю запись!
ЗАЧЕМ??? юзеру 30-я запись???
Да лана. Не нужна ему именно 30-я, но хочется быть спозиционированным _примерно_ в то место курсора где был. Вполне законное желание. А тут - хоть циклом по RecNo, хоть букмаркой (которая вообще-то делает то же самое, потому валидна почти всегда, невалидна только если курсор укоротился настолько, что она кажет за его пределы). Это после делета. Апдейты-инсёрты через RefreshSQL обычно рефрешатся, без переоткрытия (хотя есть и постановки, требующие фуллрефреша).

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 июл 2006, 15:45

Merlin писал(а):Да лана. Не нужна ему именно 30-я, но хочется быть спозиционированным _примерно_ в то место курсора где был.
Определить, где это "примерно" можно только в очень конкретном случае, опираясь на текущие сортировочные поля, если такие есть. Понятие "соседние" зависят от очень разных параметров.

Rambos
Сообщения: 11
Зарегистрирован: 17 июн 2006, 13:02

Сообщение Rambos » 05 июл 2006, 15:52

CyberMax писал(а):Ну-ну. Получаем закладку, потом открываем набор...
Всмысле не открываем а переоткрываем (обновляем)
Подразумевается что до обновления набор был открыт

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 июл 2006, 16:02

WildSery писал(а):Определить, где это "примерно" можно только в очень конкретном случае, опираясь на текущие сортировочные поля, если такие есть. Понятие "соседние" зависят от очень разных параметров.
Разумеется. Если за время редатирования интенсивность вставок-удалений больше экрана, то говорить не об чем. Но даже в этом случае если в курсоре, скажем, около 1000 записей и юзер жевал 600-ю, то, как правило, ему после этого ближе отмахивать к следующей интересующей примерно от середины, чем от начала.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 июл 2006, 19:47

Merlin писал(а):...около 1000 записей и юзер жевал 600-ю...
:shock: такой грид не имеет права на существование, т.к. пользователь сразу перегрузится информацией. Только с неотключаемыми фильтрами, даже если "надо" такое.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 июл 2006, 20:41

WildSery писал(а):
Merlin писал(а):...около 1000 записей и юзер жевал 600-ю...
:shock: такой грид не имеет права на существование, т.к. пользователь сразу перегрузится информацией. Только с неотключаемыми фильтрами, даже если "надо" такое.
Правда? Ну, спасибо, просветил. Пример раз. Ценовые группы номенклатора. Главный фильтр - starting. А он не помнит точно на что оно стартинг, особенно когда оно не по-русски стартинг. А в чухонском языке, например, буквица пишется "Y", а читается "Ю". Не, дополнительные фильтры есть конечно - типа с наличием на складах такой-сякой линии поставки, с отклонением усреднённой себестоимости в границах диапазона на такой-сякой линии поставки, с наличием в производственных заказах, с себестоимостью в диапазоне, уценка-нет, валюта закупки, собственное производство-перепродаваемый товар-сырьё для производства, применяемая схема ценообразования и ряд её параметров... И когда босс занимается аналитикой, он иной раз чешет репу и ими и пользуется. А человек, работающий со списком постоянно, быстрей эту несчастную тыщу колёсиком мыша прокрутит и среагирует на семафорную подсветку в том или ином столбце. Это ж не десятки тыщ, а всего лишь тыща. Пример два - тованый состав одной ценовой группы. Есть такие, в которых по одному товару, а есть и по тыще. Что, тоже мурыжить его всегда входом через фильтр-форму? Ой спасибо он тебе скажет... Таких примеров я тебе тыщу могу привести. Вот если таким манером крутят многотысячный товарный номенклатор целиком, да ещё по мудему - оно конешно.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 июл 2006, 21:19

Во всех твоих примерах нет непосредственной работы с объектами - редактирования, добавления, удаления. Фактически, это у тебя динамический отчёт. Если же хочешь именно оперировать такими объёмами объектов - стоит подумать, возможно, что ты сам не знаешь, чего хочешь, и пытаешься решить это таким способом.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 июл 2006, 21:31

:-D Я плачу, я просто плачу :-D Человек меряет все задачи на СУБД исключительно редактированием состава накладной, ну ладно, хрен с ним, даже с проходом через список заголовков накладных, и обвиняет меня, у которого в поcледней действующей системе сумма объёма 21 непересекающейся функциональности ехешника, написанных в разных технологиях и под разные платформы, как OLTP, так и OLAP, работающих с одной базой из сотни точек на пространстве от Минска и Хельсинки до Владивостока, включая новые азиатские страны, давно перевалил за сотню мегов, в узости кругозора :-D Мил человек, ну не бывает чиста черного и чиста белого, панимаш, не-бы-ва-ет :-D

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 06 июл 2006, 01:35

Rambos писал(а):Всмысле не открываем а переоткрываем (обновляем)
Подразумевается что до обновления набор был открыт
С каких это пор команда Open переоткрывает набор? Там тогда перед Open Close должен стоять...
Народ, предлагаю прекратить разговоры о необходимости вывода сотни/тысячи/десяти тысяч строк. Ситуации бывают разные.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 06 июл 2006, 12:00

Merlin писал(а):...и обвиняет меня, у которого в поcледней действующей системе...
Давайте без Фрейда. Признаю, в Минске и Хельсинки нашего филиала пока нет. Автор обсуждала именно _редактирование_ набора данных. Фразу про накладные - не догнал.

По теме. В данном случае больше всего пользы вижу в FIB'овском ReopenLocate с правильно подобранными полями.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 07 июл 2006, 09:08

Марина писал(а):Всем привет!
Проблема такая. Я использую компоненты IBQuery, IBUpdateSQL, DataSource. Узменения в таблице произошли, транзакция подтвердилась, сервер передернули с клиента. У меня пользователь сидит в табличке или во вьюшке скажем где-то в середине - редактирует запись, т.е. впереди 100 записей, он редактирует 101-ю и сзади тоже 100 записей (всего в таблице 200 записей). Пока он ее редактировал, другой пользователь удалил его запись и еще 70 записей вперед. Т.е. теперь курсор надо поставить на 30-ю запись! Вопрос в том как ПРАВИЛЬНО это сделать! Помогите пожалуйста! )))
МММ, можно, конечно редактору делать холостой апдейт и занять запись, если он первый в нее залез, либо получить сообщение, что такой записи нет, если запись уже была удалена. Но это чревато тем, что редактор начав изменение записи пожет покурить пойти, а все остальные в это время конфликт транзакций получат.
при подобных массовых удалениях как может редактор заранее знать, сколько записей будет удалено? Другой (другие) могут удалить и не 70 записей, а 170.

Фанис
Сообщения: 17
Зарегистрирован: 16 июн 2005, 19:28

Re: Как ПРАВИЛЬНО ловить курсор в табл. после передер. серве

Сообщение Фанис » 04 авг 2006, 19:52

Марина писал(а):Помогите пожалуйста!
Удаляю или сохраняю запись в табличке, данные обновляются с сервера, курсор становится на 1-ю запись. Есть способы как это сделать. Вопрос в том, как ПРАВИЛЬНО это сделать, что лучше!

Код: Выделить всё

unit IBQueryA;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, IBCustomDataSet, IBQuery;

type
  TIBQueryA = class(TIBQuery)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
   procedure TableRefresh(const KeyParams: string ='');
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('InterBase', [TIBQueryA]);
end;

procedure TIBQueryA.TableRefresh(const KeyParams: string ='');
var y:TStrings;
i,xpos:integer;
Par,FirstPar:Variant;
LongVar,Stop,SetSeek:boolean;
bsc,asc:TDataSetNotifyEvent;

  procedure SetFieldName;
  var i:integer;
  begin
    for i:=0 to FieldList.Count-1 do
    begin
      if not Fields[i].IsNull then
      y.Add(FieldList[i].FullName);
    end;
  end;

  procedure SetFieldValue;
  var i:integer;
  begin
    LongVar:=false; {Variant is long?}
    if y.count>0 then
    begin
      FirstPar:=FieldByName(y[0]).Value;{First value}
      if y.count>1 then
      begin
        LongVar:=true;
        Par:=VarArrayCreate([0,y.count-1{Del first value}], varVariant);
        for i:=1 to y.count-1 do {Push other values}
        Par[i-1]:=FieldByName(y[i]).Value;
      end;
    end;
    SetSeek:=y.Count>0;
  end;

  procedure SetSeekParams;
  begin
    SetFieldName;
    SetFieldValue;
  end;

begin
SetSeek:=false;
y:=TStringList.Create;
try
  if Active then
  begin
    if Trim(KeyParams)='' then
    SetSeekParams
    else
    begin
      xPos := 1;
      while xPos <= Length(KeyParams) do
      Y.Add(ExtractFieldName(KeyParams, xPos));
      SetFieldValue;
    end;
    {execute BeforeScroll}
    if Assigned(BeforeScroll) then BeforeScroll(Self);
  end;
DisableControls;
{Hide BeforeScroll,AfterScroll}
bsc :=BeforeScroll;
asc :=AfterScroll;
BeforeScroll := Nil;
AfterScroll := Nil;
{Requery}
if Active then ReQuery else Open;
If SetSeek then begin
Stop:=false;
  while not Stop do begin
      while not Eof and
      (FieldByName(y[0]).asVariant<FirstPar) do Next;
      if Variant(FieldByName(y[0]).Value)=FirstPar then begin
      {Yes, seek first}
      Stop:=true;
        If LongVar then {Seek other}
           for i:=1 to y.Count-1 do
             if Variant(FieldByName(y[i]).value)<>
             Par[i-1] then begin
             Stop:=false;
             Break;
             end;
       end;
          if not Stop then begin
             Next;
             If Eof then Stop:=true;
          end;
  end;
end;
{execute AfterScroll}
if Assigned(Asc) then Asc(Self);
{Pop old pointers}
BeforeScroll := bsc;
AfterScroll := asc;
EnableControls;
finally
y.free;
end;
end;

end.
[Модератор: пользуемся тегом Code!]

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 04 авг 2006, 20:35

Фанис, старина, седина в бороду, бес в ребро? :-D Пропадаешь года на три, а потом выскакиваешь как чортик из табакерки и девочек на ночь глядя пугаешь? ;)

Фанис
Сообщения: 17
Зарегистрирован: 16 июн 2005, 19:28

Сообщение Фанис » 05 авг 2006, 08:31

Merlin писал(а):Фанис, старина, седина в бороду, бес в ребро? :-D Пропадаешь года на три, а потом выскакиваешь как чортик из табакерки и девочек на ночь глядя пугаешь? ;)
Привет!
Да я как все - пару недель тыкался в news.demo.ru и ... отпал.
Фанис

Марина
Сообщения: 32
Зарегистрирован: 14 дек 2005, 13:08

Сообщение Марина » 05 авг 2006, 14:44

Интересный код.... так просто фиг въедешь )))
Спасибо ребята, выйду из отпуска попробую с этим курсором чего-нибудь замутить... ))))

Фанис
Сообщения: 17
Зарегистрирован: 16 июн 2005, 19:28

Сообщение Фанис » 05 авг 2006, 16:13

Марина писал(а):Интересный код.... так просто фиг въедешь )))
Спасибо ребята, выйду из отпуска попробую с этим курсором чего-нибудь замутить... ))))
Там все просто - находим параметры (значения полей - достаточно id) для поиска требуемой записи, корректно исполняются AfterScroll and BeforeScroll, затем они = nil - чтоб не отрабатывали при поиске записи.
Применение

Код: Выделить всё

  taData.Post;
  taData.TableRefresh('id');

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 07 авг 2006, 11:29

2 Фанис:
А не проще было сделать на FIB, где ReopenLocate "родной"? ;)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 07 авг 2006, 12:49

Фанис писал(а): Да я как все - пару недель тыкался в news.demo.ru и ... отпал.
http://www.ibase.ru/conf.htm надо зарегистрироваться на гугле и гмане.

Марина
Сообщения: 32
Зарегистрирован: 14 дек 2005, 13:08

Сообщение Марина » 01 сен 2006, 11:10

Спасибо за помощь, все по-другому у себя перелепила, как на собеседование съездила, фокус подсказали с транзакциями и внешними ключами и проблема курсора убирается сама.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 01 сен 2006, 11:18

Не вижу связи между транзакцией, внешним ключом и курсором. Можно поподробнее?

Ответить