Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка добавления записи [D5, XP]


Евгений Р. ©   (2007-06-20 12:51:00) 

Есть простейшая процедура, добавляющая запись в таблицу.
Процедура работает замечательно, но когда она запускается в цикле, то около 20го повтора выдается ошибка: Read failure file: c:\...\aspos
Мнение о БДЕ у большинства мне известно.
Что можно сделать ?

procedure tSpos.SaveToArxiv(dtVys:integer;tmVys:double);
 var at:Ttable;
Begin
  at:=Ttable.create(nil);
  at.DataBaseName:='MainVest';
  at.TableName:='aSpos.dbf';
  at.open;
  at.append;

  at.fieldByName('Opr1').asstring:=opr1;
  at.fieldByName('Opr2').asstring:=opr2;
  at.fieldByName('Opr2Ank').asstring:=opr2Ank;
  at.fieldByName('Nomerdoc').asInteger:=NomerDoc;
  at.fieldByName('Nomer').asInteger:=nomer;
  at.fieldByName('Datap').asDateTime:=DataP;
  at.fieldByName('Timep').asInteger:=TimeP;
  at.fieldByName('DatapF').asDateTime:=DataPF;
  at.fieldByName('TimepF').asFloat:=TimePF;

  at.fieldByName('Pbrn').asBoolean:=pBrn;
  at.fieldByName('PRnz').asBoolean:=PRnz;
  at.fieldByName('Rnz' ).asFloat:=Rnz;

  at.fieldByName('Vdtrf').asInteger:=VdTrf;
  at.fieldByName('TipProg').asInteger:=TipProg;
  at.fieldByName('Strana').asstring:=upper(Strana);
  at.fieldByName('KodStrany').asInteger:=KodStrany;

  at.fieldByName('F').asstring:=upper(f);
  at.fieldByName('I').asstring:=upper(i);
  at.fieldByName('O').asstring:=upper(o);
  at.fieldByName('Pol').asInteger:=pol;
  at.fieldByName('Pbezpods').asBoolean:=pBezPods;
  at.fieldByName('Mest').asInteger:=Mest;
  at.fieldByName('Pdopmest').asBoolean:=pDopMest;
  at.fieldByName('Pbeznal').asBoolean:=pBeznal;
  at.fieldByName('PStraxovki').asBoolean:=PStraxovki;
  at.fieldByName('Compname').asstring:=CompName;
  at.fieldByName('Usercod').asInteger:=UserCod;

  at.fieldByName('NameGrup').asstring:=NameGrup;
  at.fieldByName('nZayavki').asInteger:=nZayavki;
  at.fieldByName('KodStrany').asInteger:=KodStrany;

  at.fieldByName('Datavys').asDateTime:=dtVys;// date;
  at.fieldByName('Timevys').asInteger:=jTimeFromDateTime(tmVys); //jTimeFromDateTime(time);
  at.fieldByName('DatavysF').asDateTime:=date;
  at.fieldByName('TimevysF').asFloat:=time; //jTimeFromDateTime(time);

  at.fieldByName('Userkodvys').asInteger:=getUserCod;
  if sprPort>0 then
     at.fieldByName('sprPort').asInteger:=sprPort;

  at.post;
  at.close;
  at.free;
End;{SaveToArxiv}


Gloomer   (2007-06-20 16:51:00) [1]

а если вытащить переменную atиз процедуры за цикл?

at:=TTable.Create(nil);
for i:=0 to list.count-1 do
 begin
   list[i].SaveToArxiv;
   at.Close;
 end;
at.Free;


Desdechado   (2007-06-20 16:02:00) [2]

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


Sergey13   (2007-06-20 15:52:00) [3]

> [10] Евгений Р.   (20.06.07 15:49)

Сделай внешнюю процедуру для показанной, где будет открытие, запуск цикла со старой модифицированной процедурой, закрытие.

Впрочем дело твое. Я не собираюсь тебя уговаривать.


Евгений Р.   (2007-06-20 15:49:00) [4]

Обычно:
  sp.SaveToArxiv
и никаких открытий, закрытий.
Для группы - цикл (см.выше)


Sergey13   (2007-06-20 15:36:00) [5]

> [8] Евгений Р.   (20.06.07 15:32)
> Если в параметре передавть tTable, то будет некрасиво для одной записи.

У тебя в разве разные таблицы пишется? Судя по коду в одну. Открой ее и в цикле вставь записи, потом закрой.
И вообще лучше наверное запросами пользоваться.


Евгений Р.   (2007-06-20 15:32:00) [6]


> А можно сделать универсальное сохранение. Просто вынеси
> откытие/закрытие за цикл (который может делать и всего 1
> итерацию).


for i:=0 to list.count-1 do
            list[i].SaveToArxiv;

Если в параметре передавть tTable, то будет некрасиво для одной записи.


> Это наводит на мысль об известном существующем ограничении
> на размер блокируемых dbf-данных в контексте одной и той
> же пишущей транзакции.


Я думаю, что-то здесь, т.е. как слить буфер? Ведь в сети все ОК!


Sergey13   (2007-06-20 14:52:00) [7]

> [4] Евгений Р.   (20.06.07 13:49)
> Можно сделать групповое сохранение, но здесь нет смысла.

А можно сделать универсальное сохранение. Просто вынеси откытие/закрытие за цикл (который может делать и всего 1 итерацию).


Евгений Р.   (2007-06-20 14:45:00) [8]

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


zorik   (2007-06-20 14:13:00) [9]

Может поставить еще один TDataBase, который будет работать только с этой процедурой, и к нему присоеденять эту таблицу. Перед процедурой соеденять, а после отключать


Евгений Р.   (2007-06-20 13:49:00) [10]

Эта процедура - переносит текущий объект в архив.
Обычно работают с одиночным объектом. И никогда проблем не было. Но изредка однотипные операции проводят с группой объектов. Сейчас случилось 200. Тоесть, не один о. сохраняет себя 200 раз, а 200 о. сохраняют себя по 1 разу. Можно сделать групповое сохранение, но здесь нет смысла.
Без try-finally конечно не культурно, но дело не спасет. После первого же вылета при повторной попытке сохранения возникает ошибка типа "previvous error". ТОлько после выхода и нового запуска может обработаться еще 20 объектов.
Сейчас заметил, что в сети проблемы нет. Сразу обрабатываются все 200 записей.
Думаю, что на локалке BDE держит изменения в буфере и его не хватает.
Может както можно буфер сливать?


Сергей М.   (2007-06-20 13:35:00) [11]


> Евгений Р.   (20.06.07 12:51)


> Что можно сделать ?


Для начала отказаться от TTable в пользу TQuery.


> около 20го повтора


Это наводит на мысль об известном существующем ограничении на размер блокируемых dbf-данных в контексте одной и той же пишущей транзакции.

dbf-контейнер при его модификации в контексте ТА блокируется драйвером (в т.ч. входящим в состав BDE) постранично, размер страницы фиксирован и недоступен для изменения.


Desdechado   (2007-06-20 12:59:00) [12]

А зачем в цикле на каждую запись открывать/закрывать таблицу?
Я уж не говорю об отсутствующем try-finally


Virgo_Style   (2007-06-20 12:57:00) [13]

Может, не надо так часто делать create-open-close-free?


Наверх

Титульная страница Поиск, карта сайта Написать письмо