AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird: Datensatz wird nicht gefunden, obwohl er da ist

Firebird: Datensatz wird nicht gefunden, obwohl er da ist

Ein Thema von BlueStarHH · begonnen am 28. Mär 2018 · letzter Beitrag vom 29. Mär 2018
Antwort Antwort
Seite 1 von 4  1 23     Letzte » 
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
797 Beiträge
 
Delphi 11 Alexandria
 
#1

Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 14:15
Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC
Ich habe u.a. 3 Tabellen
Code:
Kunden
---------------
KdNr
...

Rechnungen
---------------
KdNr   -> FK auf Kunden.KdNr
RgNr  
ErsetztRgNr -> FK auf Rechnungen.RgNr
...

Notizen
---------------
RgNr       -> FK auf Rechnungen.RgNr
NotizNr
...
Ein Kunde kann x Rechnungen haben. Eine Rechnung kann x Notizen haben. Eine Rechnung kann durch eine andere ersetzt werden, falls Sie z.B. storniert wurde (Feld ErsetztRgNr).

So kommt es nun zum Fehler:
Benutzer A wählt Kunde 17 aus und hat heute eine neue Notiz zur Rechnung 4 angelegt (Notizen.RgNr = 4). Die Notiz kann nicht mit DataSet.Post gespeichert werden, da folgende Meldung erscheint:
Zitat:
violation of FOREIGN KEY constraint "FK_Notizen_1" on table "Notizen". Foreign key reference target does not exist. Problematic key value is ("RgNr" = 4)

Benutzer B wählt auch Kunde 17 aus und hat heute eine neue Rechnung angelegt, die Rechnung 5 ersetzt (Rechnungen.ErsetztRgNr = 5). Die neue Rechnung kann nicht mit DataSet.Post gespeichert werden, da folgende Meldung erscheint:
Zitat:
violation of FOREIGN KEY constraint "FK_Rechnungen_1" on table "Rechnungen". Foreign key reference target does not exist. Problematic key value is ("ErsetztRgNr" = 5)

Der Kundendatensatz existiert schon seit Jahren und wurde laut Aussagen der Benutzer nicht geändert (nicht prüfbar, ob das stimmt). Beide Benutzer nutzen die Software auf Ihrem eigenen PC. Die DB liegt auf dem Server.

Beide Rechnungen (4 und 5) werden im Programm angezeigt. Rechnung 5 habe ich nochmal mit SQL geprüft: Mit select * from Rechnungen where RgNr = 5 wird die Rechnung 5 zurückgegeben. Beide Benutzer können bei anderen Kunden Notizen oder Rechnungen ohne Probleme anlegen. Es betrifft nur den Kunden mit KdNr 17. Komisch ist ja, dass beide Rechnungen 4 und 5 nicht direkt miteinander verknüpft sind, aber beide Probleme bereiten.

Eben hat Benutzer A die Software neu gestartet. Problem immer noch da. Dann haben beide Benutzer die Software beendet und neu gestartet. Nun können beide ihre neuen Datensätze anlegen und posten.

Ich habe mir jeweils eine Kopie mit gbak.exe und mit einfachem Kopieren der DB-Datei gezogen. Nach einspielen der Kopien hier, lässt sich der Fehler nicht reproduzieren. Die Kopien wurden gezogen, nachdem einer von beiden Benutzer die Software neu gestartet hatte.

Wer hat eine Idee, was die Ursache des Fehler ist? Und wie ich ihn ggf. nachstellen und in Zukunft vermeiden könnte.

Geändert von BlueStarHH (28. Mär 2018 um 14:23 Uhr)
  Mit Zitat antworten Zitat
bnreimer42

Registriert seit: 26. Mai 2013
Ort: Erlangen, Franken
122 Beiträge
 
Delphi 12 Athens
 
#2

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 14:27
Bitte DDL hier posten.

Sonst kann man nur raten, was die Ursache sein kann.

Was gibt

Code:
select * from Rechnungen where RgNr = 4
zurück?
Björn Reimer
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.400 Beiträge
 
Delphi 7 Professional
 
#3

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 14:28
Wenn die beiden zufällig gleichzeitig die Änderungen durchgeführt haben, könnte es bei einem ungeschickten Transaktionshandling zu einer derartigen Situation kommen.

Der eine kann schon das Neue sehen, der andere noch nicht, aber beim Alten ist es genau umgekehrt.

Mein erster Ansatz wäre hier den Quelltext der Stellen, an denen diese Änderungen durchgeführt werden, dahingehend zu prüfen, ob das Transaktionshandling dort korrekt ist.

Etwas Literatur zum Thema: IBPhoenix - Understanding Firebird Transactions

Geändert von Delphi.Narium (28. Mär 2018 um 15:09 Uhr) Grund: Schreibfehler
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
797 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 14:40
Der eine kann schon das Neue sehen, der andere noch nicht, aber beim Alten ist es genau umgekehrt.
Beide Benutzer arbeiten mit unterschiedlichen Rechnungen (4 und 5). Wie sollte das alt vs. neu also hier hereinspielen?

Geändert von BlueStarHH (28. Mär 2018 um 15:03 Uhr)
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
797 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 14:44
Mein erster Ansatz wäre hier den Quelltext der Stellen, an denen diese Änderungen durchgeführt werden, dahingehend zu prüfen, ob das Transaktionshandling dort korrekt ist.
Ein Transaktionshandling gibt es im Quellcode nicht. Der Code ist ein simples DataSet.Insert und dann eine DataSet.Post nachdem der Benutzer die Felder in der GUI gefüllt hat. Das Transaktionshandling ist in den IBDAC-Komponenten eingestellt:

Lockmode = lmLockImmediate
AutoCommit = true
IsolationLevel = iblReadCommitted
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
797 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 15:00
Bitte DDL hier posten.

Sonst kann man nur raten, was die Ursache sein kann.
SQL-Code:
CREATE TABLE Kunden (
    KdNr VARCHAR(15) CHARACTER SET ASCII NOT NULL,
    ...
)
ALTER TABLE Kunden ADD CONSTRAINT PK_Kunden PRIMARY KEY (KdNr);
   
   
CREATE TABLE Rechnungen (
    KdNr VARCHAR(15) CHARACTER SET ASCII NOT NULL,
    RgNr VARCHAR(25) CHARACTER SET ASCII NOT NULL,
    ErsetztRgNr VARCHAR(25) CHARACTER SET ASCII,
    ...
)
ALTER TABLE Rechnungen ADD CONSTRAINT PK_Rechnungen PRIMARY KEY (RgNr);
ALTER TABLE Rechnungen ADD CONSTRAINT FK_Rechnungen_1 FOREIGN KEY (ErsetztRgNr) REFERENCES Rechnungen (RgNr);
ALTER TABLE Rechnungen ADD CONSTRAINT FK_Rechnungen_2 FOREIGN KEY (KdNr) REFERENCES Kunden (KdNr) ON DELETE CASCADE ON UPDATE CASCADE;


CREATE TABLE Notizen (
    NotizNr INTEGER NOT NULL,
    RgNr VARCHAR(25) CHARACTER SET ASCII,
    NOTIZ BLOB SUB_TYPE 1 SEGMENT SIZE 80
    ...
);
ALTER TABLE Notizen ADD CONSTRAINT PK_Notizen PRIMARY KEY (NotizNr);
ALTER TABLE Notizen ADD CONSTRAINT FK_Notizen_1 FOREIGN KEY (RgNr) REFERENCES Rechnungen (RgNr) ON DELETE CASCADE ON UPDATE CASCADE;
Was gibt

Code:
select * from Rechnungen where RgNr = 4
zurück?
Das zeigt jetzt die Rechnung 4. Zum Zeitpunkt des Fehlers habe ich das nicht abgefragt. Die Rechnung 4 wurde aber im DB Grid zum Fehlerzeitpunkt angezeigt. Auch hier nochmal der Hinweis: Es handelt sich bei dem Fehler um 2 Rechnungen (4 und 5) die nichts miteinander zu tun haben und die auch nicht wechselseitig von den Benutzern bearbeitet wurden. Je der Benutzer hat ausschließlich mit 4 oder 5 gearbeitet.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.400 Beiträge
 
Delphi 7 Professional
 
#7

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 15:08
Sie arbeiten mit unterschiedlichen Rechnungen aber mit dem gleichen Kunden.

Wie sehen die Statements aus, mit denen die Datasets gefüllt werden?
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
529 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 15:20
Es sind Varchar-Felder, über die die Tabellen verknüpft werden. Ist zwar möglich, aber auch gefährlich, da man z.B. am Bildschirm Leerzeichen nicht sieht. Besser alles über Int-Werte verknüpfen und sicherstellen, das diese nicht mehrfach vergeben werden können, z.B. mit Generatorwerten.
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 15:25
Künstliche Schlüssel (Schlüsselfeld nicht Teil der Daten) sind m.E. immer zu bevorzugen. Zudem sollte man die Erzeugung der Werte dem Server überlassen, er kann so sicherstellen, dass diese immer eindeutig sind.
Markus Kinzler
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
797 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Firebird: Datensatz wird nicht gefunden, obwohl er da ist

  Alt 28. Mär 2018, 15:27
Wie sehen die Statements aus, mit denen die Datasets gefüllt werden?
Für die Rechnung:
Delphi-Quellcode:
if InsertAtBegin then
begin
  Rechnungen.First;
  Rechnungen.Insert;
end
else
  Rechnungen.Append;

Rechnungen.FieldByName('RgNr').asString := GetNewRgNr;
Rechnungen.FieldByName('KdNr').asString := Kunden.FieldByName('KdNr').asString;
Rechnungen.FieldByName('Datum').asDateTime := Date;
...usw für alle Felder
Dann kann der Nutzer noch Daten über DBEdits/Grid ergänzen und drückt dann einen Button mit:
Rechnungen.Post;

Für die Notiz:
Delphi-Quellcode:
Notizen.Insert;
Notizen.FieldByName('NotizNr').asString := GetNewNotizNr;
Notizen.FieldByName('RgNr').asString := Rechnungen.FieldByName('RgNr').asString;
Notizen.FieldByName('Notiz').asString := 'ABC';
Notizen.Post;
GetNewXXXXNr fragen einfach einen Generator ab.
  Mit Zitat antworten Zitat
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 03:23 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