Einzelnen Beitrag anzeigen

sancho1980

Registriert seit: 7. Feb 2006
429 Beiträge
 
#1

programmabsturz bei update nach event

  Alt 16. Nov 2006, 14:45
Datenbank: firebird • Version: 1.5 • Zugriff über: ibx und zeos
hallo

ich hab gerade ein ziemlich verzwicktes problem; vielleicht kann mir einer helfen

es geht hier (immer noch) um einer terminologie-datenbank: die datenbank hat unter anderem eine tabelle DICENTRIES; ein eintrag der tabelle DICENTRIES hat widerum unter anderem die folgenden felder:

ID (bigint): ist Primary Key
TERM (varchar): speichert die Benennung des Eintrags (also der "Begriff", der im Wörterbuch auffindbar ist)
VERWID (bigint): beinhaltet die ID der Hauptbenennung, falls der betreffende Eintrag ein Synonym sein sollte (ansonsten ist das feld null)
VERWTERM (varchar): speichert das feld TERM der Hauptbenennung, falls der betreffende Eintrag ein Synonym sein sollte (ansonsten is das feld null); dieses feld wird bei änderung des haupteintrags automatisch geupdatet


in meiner clientanwendung sind jetzt stets 2 datasets geöffnet:


DatasetDicentries: hat immer 20 Einträge aus tabelle DICENTRIES geöffnet (es können hier AUCH Synonyme geöffnet sein; also "where VERWID is not null")
DatasetSynonyms: ist slave von DatasetDicentries und hat immer sämtliche Synonyme des gerade selektierten Eintrags aus DatasetDicentries geöffnet (also "where VERWID = :ID")



desweiteren existieren in meiner datenbank trigger, die folgendes tun:

-nach einem update eines eintrags aus DICENTRIES wird folgendes event gepostet:

post_event 'update ' || new.id || ' dicentries' -nach einem delete eines eintrags aus DICENTRIES wird folgendes event gepostet:

post_event 'delete ' || old.id || ' dicentries'
wozu diese events? nun, es kann ja sein, dass ein eintrag, der DatasetSynonyms geöffnet ist, auch gleichzeitig in DatasetDicentries geöffnet ist. Wird jetz besagter Eintrag in einem der besagten verändert oder gelöscht, so soll das in dem anderen dataset sichtbar werden

nach dem öffnen von DatasetDicentries registriert das dataset automatisch die geöffneten records auf veränderung oder löschung:

Delphi-Quellcode:
while not self.DataSetDicentries.Eof do
    begin
      self.DicentriesAlerter.Events.Add('update ' + IntToStr(self.DataSetDicentriesID.AsLargeInt) + ' dicentries');
      self.DicentriesAlerter.Events.Add('delete ' + IntToStr(self.DataSetDicentriesID.AsLargeInt) + ' dicentries');
      self.DataSetDicentries.Next();
    end;
DatasetSynonyms macht das selbe, nur, dass es sich bloß für diejenigen einträge registriert, die nicht schon in DatasetDicentries geöffnet sind (wenn ein Eintrag verändert wird, der sowohl in DatasetDicentries als auch in DatasetSynonyms geöffnet ist, dann braucht davon nur das Master-Dataset etwas wissen, denn das Slave Dataset wird nach einem Refresh des Masters ja automatisch neu geöffnet):

Delphi-Quellcode:
while not self.DataSetSynonyms.Eof do
    begin
      if self.DicentriesAlerter.Events.IndexOf('update ' + IntToStr(self.DataSetASSynonymsID.AsLargeInt) + ' dicentries') = -1 then
        begin
          self.SynonymsAlerter.Events.Add('update ' + IntToStr(self.DataSetSynonymsID.AsLargeInt) + ' dicentries');
          self.SynonymsAlerter.Events.Add('delete ' + IntToStr(self.DataSetSynonymsID.AsLargeInt) + ' dicentries');
        end;
      self.DataSetSynonyms.Next();
    end;
wenn jetzt der eventalerter für DatasetDicentries ein Event erhält, geschieht folgendes:

Delphi-Quellcode:
procedure TDataModule1.DicentriesAlerterEventAlert(Sender: TObject;
  EventName: String; EventCount: Integer; var CancelAlerts: Boolean);
var
  id: Int64;
  bm: TBookMark;
begin
  bm := self.DataSetDicentries.GetBookmark();
  id := StrToInt64(Tokenize(EventName, ' ')[1]);
  self.DataSetDicentries.First();
  while self.DataSetDicentriesID.Value <> id do
    self.DataSetDicentries.Next();
  if Tokenize(EventName, ' ')[0] = 'updatethen
    self.DataSetDicentries.Refresh()
  else
    self.DataSetDicentries.Delete();
    self.DataSetDicentries.GotoBookmark(bm);
end;
wenn also in DatasetSynonyms ein Eintrag geändert oder gelöscht wird, dann wird der Master DatasetDicentries über ein Event darüber informiert und refresht oder deletet den entsprechenden eintrag auch. das problem jetzt ist aber: bei einem refresh klappt das tadellos, aber bei einem delete friert mein programm ein!
zuerst dachte ich, das problem hängt damit zusammen, das man nicht einen eintrag löschen kann, der bereits einmal gelöscht wurde, aber daran liegts nicht:
angenommen ich kommentiere self.DataSetDicentries.Delete(); im handler aus und lösche den besagten eintrag aus DatasetDicentries per Hand noch einmal, dann friert das programm nicht ein..es gibt nicht mal eine fehlermeldung von der datenbank, dass ich einen eintrag lösche, der ja gar nicht mehr existiert...
wie also bekomme ich den bereits aus der datenbank gelöschten eintrag automatisch aus DatasetDicentries entfernt??

weiß einer weiter?

danke,

martin
Um Rekursion zu verstehen, muss man zunächst Rekursion verstehen.
  Mit Zitat antworten Zitat