Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Entweder BOF oder EOF oder Datensatz gelöscht (https://www.delphipraxis.net/151310-entweder-bof-oder-eof-oder-datensatz-geloescht.html)

hyype 12. Mai 2010 11:01

Datenbank: mssql2005 • Zugriff über: ado

Entweder BOF oder EOF oder Datensatz gelöscht
 
So, die Fehlermeldung ist hinreichend bekannt, allerdings eigentlich nur den Programmierern, die noch mit delphi 5.0 arbeiten, da brauchte es einen Patch.
Das Problem ist, ich verwende turbo delphi, da dürfte ich ja den Patch nicht benötigen.
Ich teile euch mal mit, wie der Fehler zustande kommt:

Delphi-Quellcode:
    adoq.SQL.Text := hypes_sql;
    adoq.cachesize:=20;
    adoq.disablecontrols;
    adoq.open;
    adoq.enablecontrols;
    if adoq.recordcount>0 then
      adoq.Delete;
Ich setze cachesize auf einen Wert > 1, mache disablecontrols, open (holt nur genau einen Datensatz), enablecontrols und schließlich ein delete -> Fehler! (und zwar beim delete!)
Lasse ich disablecontrols und enablecontrols beim öffnen weg, geht es.
Lasse ich cachesize auf 1, kommt der Fehler auch nicht.

Hintergrund ist diese procedure aus adodb:

Delphi-Quellcode:
procedure DoRecordsetDelete(DataSet: TCustomADODataSet; AffectRecords: TAffectRecords);
begin
  with DataSet do
  try
    Recordset.Delete(AffectRecordsValues[AffectRecords]);
    { When CacheSize > 1, Recordset allows fetching of deleted records.
      Calling MovePrevious seems to work around it }
    if (CacheSize > 1) and (PRecInfo(ActiveBuffer).RecordNumber <> 1) then
    begin
      Recordset.MovePrevious;
      Recordset.MoveNext;
    end;
    Recordset.MoveNext;
  except
    on E: Exception do
    begin
      Recordset.CancelUpdate;
      DatabaseError(E.Message);
    end;
  end;
end;
wenn cachesize > 1 und blabla.recordnumber<>1 dann
mache was, was den Fehler wirft ^^

cachesize>1 ist klar, aber recordnumber ist interessant, denn:
mit disablecontrols vorm open ist recordnumber an der Stelle <>1, ohne disablecontrols vorm open ist es 1.
dann geht der in die if-Anweisung, macht moveprevious und movenext und danach will er nochmal movenext machen und das knallt dann.
Frage ist jetzt, was ich dagegen tun kann.

Vielen Dank!

mfg

hyype

hyype 12. Mai 2010 15:06

Re: Entweder BOF oder EOF oder Datensatz gelöscht
 
habe weiter gesucht, hier mal ein Code-Auszug der function TCustomADODataSet.InternalGetRecord, welche bei einem adoquery.open durchlaufen wird:

Delphi-Quellcode:
if ControlsDisabled then
  RecordNumber := -2 else
  RecordNumber := Recordset.AbsolutePosition;
Hier sehen wir sehr schön, wie sich disablecontrols auf die recordnumber auswirkt...

Ich glaube ja fast, dass das 2. movenext (siehe obiger post) in den else-Zweig der if-Anweisung gehört und nicht hinter die if-Anweisung bzw alternativ das movenext in der if-Anweisung zuviel ist, so dass movenext in jedem Falle nur einmal aufgerufen wird, wie seht ihrs?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz