Форум: "Начинающим";
Текущий архив: 2007.07.15;
Скачать: [xml.tar.bz2];
Вниз
Ошибка добавления записи Найти похожие ветки
← →
Евгений Р. (2007-06-20 12:51) [0]Есть простейшая процедура, добавляющая запись в таблицу.
Процедура работает замечательно, но когда она запускается в цикле, то около 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}
← →
Virgo_Style © (2007-06-20 12:57) [1]Может, не надо так часто делать create-open-close-free?
← →
Desdechado © (2007-06-20 12:59) [2]А зачем в цикле на каждую запись открывать/закрывать таблицу?
Я уж не говорю об отсутствующем try-finally
← →
Сергей М. © (2007-06-20 13:35) [3]
> Евгений Р. (20.06.07 12:51)
> Что можно сделать ?
Для начала отказаться от TTable в пользу TQuery.
> около 20го повтора
Это наводит на мысль об известном существующем ограничении на размер блокируемых dbf-данных в контексте одной и той же пишущей транзакции.
dbf-контейнер при его модификации в контексте ТА блокируется драйвером (в т.ч. входящим в состав BDE) постранично, размер страницы фиксирован и недоступен для изменения.
← →
Евгений Р. (2007-06-20 13:49) [4]Эта процедура - переносит текущий объект в архив.
Обычно работают с одиночным объектом. И никогда проблем не было. Но изредка однотипные операции проводят с группой объектов. Сейчас случилось 200. Тоесть, не один о. сохраняет себя 200 раз, а 200 о. сохраняют себя по 1 разу. Можно сделать групповое сохранение, но здесь нет смысла.
Без try-finally конечно не культурно, но дело не спасет. После первого же вылета при повторной попытке сохранения возникает ошибка типа "previvous error". ТОлько после выхода и нового запуска может обработаться еще 20 объектов.
Сейчас заметил, что в сети проблемы нет. Сразу обрабатываются все 200 записей.
Думаю, что на локалке BDE держит изменения в буфере и его не хватает.
Может както можно буфер сливать?
← →
zorik © (2007-06-20 14:13) [5]Может поставить еще один TDataBase, который будет работать только с этой процедурой, и к нему присоеденять эту таблицу. Перед процедурой соеденять, а после отключать
← →
Евгений Р. (2007-06-20 14:45) [6]Проблема только на локалке при отладке, но нехочется ее и здесь. Думаю, должен быть культурный выход
← →
Sergey13 © (2007-06-20 14:52) [7]> [4] Евгений Р. (20.06.07 13:49)
> Можно сделать групповое сохранение, но здесь нет смысла.
А можно сделать универсальное сохранение. Просто вынеси откытие/закрытие за цикл (который может делать и всего 1 итерацию).
← →
Евгений Р. (2007-06-20 15:32) [8]
> А можно сделать универсальное сохранение. Просто вынеси
> откытие/закрытие за цикл (который может делать и всего 1
> итерацию).
for i:=0 to list.count-1 do
list[i].SaveToArxiv;
Если в параметре передавть tTable, то будет некрасиво для одной записи.
> Это наводит на мысль об известном существующем ограничении
> на размер блокируемых dbf-данных в контексте одной и той
> же пишущей транзакции.
Я думаю, что-то здесь, т.е. как слить буфер? Ведь в сети все ОК!
← →
Sergey13 © (2007-06-20 15:36) [9]> [8] Евгений Р. (20.06.07 15:32)
> Если в параметре передавть tTable, то будет некрасиво для одной записи.
У тебя в разве разные таблицы пишется? Судя по коду в одну. Открой ее и в цикле вставь записи, потом закрой.
И вообще лучше наверное запросами пользоваться.
← →
Евгений Р. (2007-06-20 15:49) [10]Обычно:
sp.SaveToArxiv
и никаких открытий, закрытий.
Для группы - цикл (см.выше)
← →
Sergey13 © (2007-06-20 15:52) [11]> [10] Евгений Р. (20.06.07 15:49)
Сделай внешнюю процедуру для показанной, где будет открытие, запуск цикла со старой модифицированной процедурой, закрытие.
Впрочем дело твое. Я не собираюсь тебя уговаривать.
← →
Desdechado © (2007-06-20 16:02) [12]> и никаких открытий, закрытий.
Тебе проблему решить или принципы свои выпятить надо?
← →
Gloomer © (2007-06-20 16:51) [13]а если вытащить переменную at из процедуры за цикл?
at:=TTable.Create(nil);
for i:=0 to list.count-1 do
begin
list[i].SaveToArxiv;
at.Close;
end;
at.Free;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.07.15;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.038 c