AGB  ·  Datenschutz  ·  Impressum  







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

Duplicate-Value-Fehler bei Aufruf von Append

Ein Thema von Perlsau · begonnen am 5. Mai 2015 · letzter Beitrag vom 9. Mai 2015
Thema geschlossen
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 08:30
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.
Problematisch ist daran, dass du eben egal welche Exception fängst und durch den großen Einzugsbereich von try .. except eben auch für alles Möglich eine Exception bekommen kannst.

Wenn du programmtechnisch alles richtig machst, dann wird diese Lösung exakt das machen, was du davon erwartest. Somit also keine Einwände.

Die Probleme fangen immer dann an, wenn es aus welchen Gründen auch immer in dem gekennzeichneten Bereich zu einer Exception kommt:
Delphi-Quellcode:
  Try

    {problematischer Bereich Anfang}

    DatMod.Qset_Personen.Append;
    Feld_Id.AsInteger := Id;
    Feld_Name.AsString := Person;
    If DateExists Then
    Feld_Datum.AsDateTime := Datum;

    {problematischer Bereich Ende}

    DatMod.Qset_Personen.Post;
    Result := True;
  Except
dann reagierst du so, als ob es sich um ein Duplikat handelt.

Besser wäre es zumindestens schon mal das so umzustellen

Delphi-Quellcode:
Function TFrame_PersonenAktuell.Eintragen(Id : Integer; Person : String; Datum : TDateTime; DateExists : Boolean) : Boolean;
begin
  DatMod.Qset_Personen.Append;
  Feld_Id.AsInteger := Id;
  Feld_Name.AsString := Person;
  If DateExists Then
  Feld_Datum.AsDateTime := Datum;

  Try
    // Nur Post-Methode abfangen
    DatMod.Qset_Personen.Post;
    Result := True;
  Except
    // Eine Einschränkung auf den konkreten Exception-Typ wäre noch besser
    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;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
 
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 09:42
Also ich seh das nicht so problematisch, da jede Exception abgefangen und mit der original Message gelogged(!) wird und im Fall eines bestimmten, ggF. problematischen Datasetstate, genau dieser State/ Fall behandelt wird (unabhängig von der exakten Fehlermeldung, aber abhängig eben vom State). Es geschieht hier also nichts falsches.
Ein spezifischeres Exception Handling kann nur in Kombi mit dem allgemeinen geschehen und ist auch nur dann sinnvoll, wenn eine spezifische, dazu passende Codesequence folgt.

Vielleicht ist schon das verschieben des Try Blocks auf das Post problematisch, wenn es bei der Wertezuweisung ins Dataset knallt.
Gruß, Jo
 
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 10:19
Operationen mit DataSet/Connection laufen doch immer nach dem gleichen Muster ab:
Delphi-Quellcode:
procedure Bar;
begin
  DataSet.Append;
  try
 
    DataSet.FieldByName('foobar').Value := 'bar from foo';

    DataSet.Post; // letzte Aktion im try..except Block
  except
    DataSet.Cancel;
    raise;
  end;
end;

procedure Foo;
begin
  Connection.StartTransaction;
  try
 
    Bar;
    ... (beliebig viele)
    Bar;

    Connection.Commit; // letzte Aktion im try..except Block
  except
    Connection.Rollback;
    raise;
  end;
end;
Das kann man fast reflexartig einsetzen und hat damit wenig Probleme, egal ob sich dort ein Programmierfehler oder Eingabefehler reingemogelt hat.

Wirft der Aufruf von Foo keine Exception, dann ist das eben erfolgreich ausgeführt worden.

Wenn man eine Exception wirklich behandeln kann, dann greift man ein und sorgt dafür, dass die Prozedur ihre geforderte Arbeit erledigen kann oder wirft eine Exception (die gleiche oder eine übersetzte, Hauptsache eine Exception).

Das Protokollieren von Exceptions geht auch ganz anders (s. Delphi-Referenz durchsuchenTApplication.OnException) und damit soger wesentlich einfacher, weil es nur an einer Stelle definiert werden muss.

Ich denke aber wir driften gerade ab ... zum Thema Exception gibt es hier (auch von mir) schon mehr als genug Beiträge ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 9. Mai 2015 um 10:23 Uhr)
 
Perlsau
(Gast)

n/a Beiträge
 
#4

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 11:06
Problematisch ist daran, dass du eben egal welche Exception fängst und durch den großen Einzugsbereich von try .. except eben auch für alles Möglich eine Exception bekommen kannst.
Echt jetzt? Für was könnte ich denn noch eine Exception bekommen?

Wenn du programmtechnisch alles richtig machst, dann wird diese Lösung exakt das machen, was du davon erwartest. Somit also keine Einwände.
Das nennt man eine Tautologie: Wenn ich dich mit Wasser begieße, bist du naß. Wenn ich alles richtig mache, gibt's keine Fehler. Ei sowas aber auch, da wäre ich in hundert Jahren nicht draufgekommen

Die Probleme fangen immer dann an, wenn es aus welchen Gründen auch immer in dem gekennzeichneten Bereich zu einer Exception kommt:
Äh – welche Probleme? Wenn es von Append bis Post bzw. Cancel zu einer Exception kommt, wird der Name nicht eingetragen und stattdessen in die Textdatei geschrieben mit einem Hinweis auf den Grund, weshalb das nicht eingetragen wurde. Wo ist denn da das Problem?

Inzwischen gibt es nicht mal mehr Doubles, die in die Textdatei geschrieben werden müssen, denn ich frage nun vor dem Append ab, ob der Name bereits eingetragen ist:
Delphi-Quellcode:
Function TAktual.Eintragen_Person(Id: Integer; Person: String; Datum: TDateTime; DateExists: Boolean): Boolean;
Var
  Z : Integer;
  Aus : String;

begin
  Z := 0;
  Aus := Person;

  While DatMod.PersonExists(Aus) Do
  Begin
    Inc(Z);
    Aus := Person + ' (' + IntToStr(Z) + ')';
  End;

  Person := Aus;

  Try
  ...
Ich kann erst später nachschauen/entscheiden/recherchieren, ob der doppelte Name dieselbe Person bezeichnet oder eben eine andere mit demselben Namen. Die Gründe hierfür zu erklären würde jetzt aber zu weit führen. Ich sehe hier nicht wirklich ein Problem, nicht mal im Ansatz. Und selbstverständlich verwende ich in anderen Fällen schon die passenden Exceptions, z.B. beim Umgang mit IdHttp:
Delphi-Quellcode:
Function TAktual.Anfrage(Var Aurl: String) : Boolean;
begin
  Try
    AUrl := IdHt.Get(Aurl);
    Result := True;
  Except
    on E: EIdHTTPProtocolException Do
    Begin
      Result := False;
      Aurl := Aurl + GLD.TS + IntToStr(e.ErrorCode);
    End;
  End;
end;
Da wird dann später anhand des Errorcodes auf den Fehler reagiert, einstweilen wird er in der aufrufenden Methode protokolliert, weshalb Aurl ein Var ist (und GLD.TS ein Trenner mit Space: ' | '). Was wäre da jetzt z.B. anders, wenn ich statt EIdHTTPProtocolException einfach Exception schreiben würde? Würde sich das Programm auch nur ein klein wenig oder sogar spürbar anders verhalten? Ich glaube kaum ...

Besser wäre es zumindestens schon mal das so umzustellen

Delphi-Quellcode:
Function TFrame_PersonenAktuell.Eintragen(Id : Integer; Person : String; Datum : TDateTime; DateExists : Boolean) : Boolean;
begin
  DatMod.Qset_Personen.Append;
  Feld_Id.AsInteger := Id;
  Feld_Name.AsString := Person;
  If DateExists Then
  Feld_Datum.AsDateTime := Datum;

  Try
    // Nur Post-Methode abfangen
    DatMod.Qset_Personen.Post;
    Result := True;
  Except
    // Eine Einschränkung auf den konkreten Exception-Typ wäre noch besser
    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;
Also mal ehrlich, lieber Sir Rufo, wieso soll denn das Dataset nach Auftreten eines Fehlers, der ja einzig und allein ein Fehler beim Post sein kann, nicht im Insert-Status sein? Eine andere Möglichkeit gibt es hier doch gar nicht mehr. Bei meiner Version können zumindest noch das Append und die Wertzuweisungen (theoretisch) Exceptions auslösen, weshalb die Abfrage des Status mehr oder weniger gerechtfertigt ist. Aber hier? Du schreibs doch selber im Kommentar: Nur Post-Methode abfangen. Was für einen Status also kann ein Dataset nach einem mißlungenen Post überhaupt haben? Richtig: dsInsert oder dsEdit. Denn wäre bereits das Append schiefgelaufen – wäre ja theoretisch möglich, weil z.B. die Verbindung zur DB nicht mehr besteht –, wäre das Programm mit einer Fehlermeldung abgestürzt. Bei mir würde es aber nicht abstürzen. Also Sachen rätst du mir, da bleib ich doch lieber bei meiner Vorgehensweise, wenn du gestattest, vielen Dank.

Geändert von Perlsau ( 9. Mai 2015 um 11:16 Uhr)
 
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 12:47
@Perlsau

Was passiert denn wenn (durch einen Programmfehler) DatMod oder QsetPersonen nicht initialisiert nil sind oder eine ungültige Referenz haben (dangling pointer)?

Dann gibt es keinen Logeintrag, weil deine Exception-Behandlung selber wieder eine Exception wirft.

Aber jeder wie er mag und es der eigenen Horizont-Linie entspricht. Wie schon gesagt, zu Exceptions und wie man damit umgeht gibt es hier genug Beiträge (auch von mir).
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
 
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 14:33
Ich glaube, Erklärungsversuche bringen nichts.

Beratungsresistenz nennt man das, glaube ich.
 
Perlsau
(Gast)

n/a Beiträge
 
#7

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 17:22
Zitat:
... und es der eigenen Horizont-Linie entspricht
Beratungsresistenz
Verucht es mit jemand anderem, ich stehe auf diesem ad hominem Niveau nicht mehr zur Verfügung.

(Es gibt Menschen, denen entgegnet man am besten gar nicht, das gibt immer nur Streß.)
 
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 18:33
Dann wird der Thread aber sinnlos, denn jemand Anderem muss man diese Banalität nicht erklären.
 
mkinzler
(Moderator)

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

AW: Duplicate-Value-Fehler bei Aufruf von Append

  Alt 9. Mai 2015, 19:06
Zitat:
Dann wird der Thread aber sinnlos
Nein, wird er nicht, weil er ursprünglich um ein anderes Thema ging, bevor hier wieder ein Nebenkriegsschauplatz der Eitelkeiten eröffnet wurde!
Wenn er der Meinung ist, dass ein Breitbandexceptionhandler hier das Mittel seiner Wahl ist und alle Arten von Ausnahmen über einen Kamm behandlet werden sollen, dann ist es seine Entscheidung, ob dass nun sinnvoll ist oder nicht.

Aber Du nutzt es mal wieder um Deine herausragende "Sozialkompetenz" unter Beweis zu stellen. Das Aufzeigen von Fehlerquellen und die Darstellung von besseren Lösungen ( wie Z.B. von Sir Rufo) ist etwas anderes als Deine pauschalen (persönlichen) Herabsetzungen!

Ich schliesse den Beitrag hier erst einmal und werde das weitere Vorgehen mit dem Team diskutieren!
Markus Kinzler
 
Thema geschlossen


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 12:14 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-2025 by Thomas Breitkreuz