AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Duplicate-Value-Fehler bei Aufruf von Append

Duplicate-Value-Fehler bei Aufruf von Append

Ein Thema von Perlsau · begonnen am 6. Mai 2015 · letzter Beitrag vom 9. Mai 2015
Thema geschlossen
Perlsau
(Gast)

n/a Beiträge
 
#1

Duplicate-Value-Fehler bei Aufruf von Append

  Alt 6. Mai 2015, 00:35
Datenbank: Firebird • Version: 2.5.2 • Zugriff über: FireDac
Gegeben ist eine Datenbank mit einer Tabelle PERSONEN:
Code:
  ID_PERSONEN INTEGER NOT NULL,
  PERS_ID     INTEGER DEFAULT 0 NOT NULL,
  PERS_NAME   VARCHAR(100) DEFAULT '' NOT NULL COLLATE UNICODE,
ALTER TABLE PERSONEN ADD CONSTRAINT PK_PERSONEN PRIMARY KEY (ID_PERSONEN);
CREATE UNIQUE INDEX IDX_PERSID ON PERSONEN (PERS_ID);
CREATE UNIQUE INDEX IDX_PERSON_NAME ON PERSONEN (PERS_NAME);
Nun werden dort Namen automatisiert eingetragen, wobei es gelegentlich vorkommt, daß ein Name bereits eingetragen ist. Da für das Feld PERS_NAME ein eindeutiger Index erstellt wurde, führt der Versuch natürlich zu einer Exception, und zwar beim Post-Befehl.

... eine Exception der Klasse EIBNativeException mit der Meldung '[FireDAC][Phys][FB]attempt to store duplicate value (visible to active transactions) in unique index "IDX_PERSON_NAME"' aufgetreten.

Das ist soweit in Ordnung, weil es abgefangen und in einer Liste dokumentiert wird, wenn ein Name bereits eingetragen ist.
Delphi-Quellcode:
Function TFrame_PersonenAktuell.Eintragen(Id : Integer; Person : String; Datum : TDateTime; DateExists : Boolean) : Boolean;
begin
  Try
    DatMod.Qset_Personen.Append;
    Feld_Id.AsInteger := Id;
    Feld_Name.AsString := Person;
    If DateExists Then
    Feld_Datum.AsDateTime := Datum;
    DatMod.Qset_Personen.Post;
    Result := True;
  Except
    On E: Exception Do
    Begin
      Result := False;
      Memo_Log.Lines.Append(e.Message + GLD.TS + IntToStr(Id));
    End;
  End;
end;
Das ist so gewollt, denn für den Anwender müssen die zu wählenden Namenseinträge später unterscheidbar sein, weil es außer dem Namen keine weiteren Unterscheidungsmerkmale gibt. Die nicht eingetragenen doppelten Namen werden später gesondert behandelt, aber das ist eine andere Geschichte. Nun aber zu meinem Problem:

Nachdem die erste Exception korrekt ausgelöst wurde, weil der Name bereits in der Datenbank existiert, folgt der nächste Name, der – von mir extra und aufs genaueste überprüft – tatsächlich noch nicht eingetragen ist. Dennoch löst der Versuch, diesen Namen einzutragen, nun ebenfalls eine Exception aus, und das – jetzt kommt's! – bereits beim Aufruf von Append! Ja, ihr habt richtig gelesen: Bereits beim Aufruf von DatMod.Qset_Personen.Append; erscheint die o.g. Fehlermeldung. Das verstehe ich jetzt erstmal überhaupt gar nicht. Wie kann ein Append einen store duplicate value auslösen? Der DB-Server weiß zu diesem Zeitpunkt doch noch gar nicht, was ihm da reingedrückt werden soll ... also irgendwas stimmt da nicht ...

Wenn ich nun im Fehlerdialog auf Anhalten drücke, landet der Prozeß-Cursor in der Unit FireDAC.Stan.Error, und zwar in der Zeile 189: raise oEx; Darüber steht was Seltsames als Kommentar: The monitor client messages queue may be not empty. When an exception is raised and an IDE is stopped, the queue remains not empty and FDMonitor does not show error message. So, give the CPU to other threads. Könnte es sein, daß ich diese monitor client messages queue (was immer das auch ist) nach einer solchen Exception erst leeren muß, damit das Programm anschließend wieder ordnungsgemäß arbeitet? Weiß jemand, was hier abläuft?
 
Perlsau
(Gast)

n/a Beiträge
 
#2

GELÖST: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 6. Mai 2015, 05:01
Dieses Problem hat mich offenbar so stark beschäftigt, daß ich ganz unruhig geschlafen habe. Vermutlich hab ich davon geträumt, erinnere mich aber nicht wirklich daran. Auf jeden Fall bin ich vor einer halben Stunde aufgewacht und mir war so gut wie klar, warum das nicht funktionieren konnte, was ich da zusammengestrickt hatte. Die Lösung: Cancel. So einfach und doch so wirkungsvoll:
Delphi-Quellcode:
Function TFrame_PersonenAktuell.Eintragen(Id : Integer; Person : String; Datum : TDateTime; DateExists : Boolean) : Boolean;
begin
  Try
    DatMod.Qset_Personen.Append;
    Feld_Id.AsInteger := Id;
    Feld_Name.AsString := Person;
    If DateExists Then
    Feld_Datum.AsDateTime := Datum;
    DatMod.Qset_Personen.Post;
    Result := True;
  Except
    On E: Exception Do
    Begin
      Result := False;
    // Das ist die Lösung: das Dataset ist noch im Insert-Mode, wenn ich es beim nächsten Mal anspreche
      If (DatMod.Qset_Personen.State = dsInsert) Or
         (DatMod.Qset_Personen.State = dsEdit) Then
          DatMod.Qset_Personen.Cancel;
      Memo_Log.Lines.Append(e.Message + GLD.TS + IntToStr(Id));
    End;
  End;
end;
Da sieht man mal wieder, daß menschliche Gehirne manchmal (oder auch öfter) erst dann auf die Lösung eines Problems stoßen, wenn man sie in Ruhe arbeiten läßt
Edit meinte noch: Abgelenkt und auf die falsche Fährte gelockt hatte mich die Fehlermeldung, die ja eigentlich die vom vorherigen Fehler war. Da wäre es doch schön, wenn Delphi melden würde, daß sich das Dateset bereits im Insert-Modus befindet ... doch dann hätten meine grauen Zellen ja nichts zu knobeln gehabt

Geändert von Perlsau ( 6. Mai 2015 um 05:14 Uhr) Grund: Edit
 
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.869 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 6. Mai 2015, 06:07
Insert und Append rufen Post auf, wenn der vorige Satz noch im Editmodus ist.
Markus Kinzler
 
Perlsau
(Gast)

n/a Beiträge
 
#4

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 6. Mai 2015, 06:24
Ahhh – ohhh .. entfleucht es mir gerade lautstark ...

Damit erklärt sich natürlich alles: Das ist nicht die alte Fehlermeldung, da wird beim zweiten Versuch, das Duplikat einzufügen, derselbe Fehler noch einmal ausgelöst. Auf so einen "gemeinen" Fallstrick muß man erst mal kommen

Danke, mkinzler, wieder was dazugelernt
 
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 6. Mai 2015, 07:43
Ich würde die Exceptionbehandlung noch verbessern: Reagiere explizit auf EIBNativeException, anstatt auf Exceptions im allgemeinen.
 
Perlsau
(Gast)

n/a Beiträge
 
#6

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 04:49
Was ist daran in welcher Hinsicht besser? Immerhin müßte ich, um deinen Vorschlag umzusetzen, eine zusätzliche Unit einbinden. Exception fängt jedoch den Fehler einwandfrei ab, das genügt mir.
 
Thema geschlossen

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz