![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка добавления записи [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?