![]() |
Datenbank: Firebird • Version: 1.5 • Zugriff über: IBSQL
Violation of foreign key constraint mit Delphi/Firebird
Hallo alle zusammen,
ich hab gerade ein kleines Problem mit Foregn Keys in meinem Projekt. Ich habe eine Tabelle "Anlagen", in der Datensätze zu Anlagen/Objekten gespeichert sind. In einer zweiten Tabelle "Schaden" werden an diesen Anlageobjekten aufgetretene Schäden gespeichert. Es kann aber auch ziemlich oft vorkommen, dass ein Schaden aufgezeichnet wurde, der bisher keiner Anlage zugeordnet ist oder wird. In Tabelle "Schaden" befindet sich ein Feld Anlagen_ID, auf dem ein Fremdschlüssel zur Anlagen_ID aus Tabelle "Anlagen"definiert ist. Der Fremdschlüssel in Tabelle "Schaden" hat als Update- und Delete-Regel SET DEFAULT (Default-Wert ist -1) definiert. In meinem bisherigen Vorgehen versuche ich nun, einen neuen Default-Datensatz anzulegen, bei dem noch kein Anlagenobjekt referenziert ist. Hier bekomme ich die besagte Fehlermeldung "Violation of foreign key constraint mit Delphi/Firebird". Ich habe auch schon SET NULL in der Update/Delete-Regel definiert und bekomme den gleichen Fehler. Kann mir jemand helfen, dieses Problem zu lösen? Vielen Dank schonmal, elliot |
Re: Violation of foreign key constraint mit Delphi/Firebird
Hi Elliot,
deine Tabellen stehen in einer master-detail Beziehung vom Typ OWNERSHIP mit der Komplexität ANLAGEN (0,1) -- SCHAEDEN (0,*). Du hast die falsche DRI rule gewählt. Nicht SET NULL oder SET DEFAULT, sondern CASCADE ist hier gefragt. In deinem Programm möchtest du darauf achten, dass der Benutzer beim Löschen von Anlagen auf vorhandene Schaeden hingwiesen wird, die automatisch mit gelöscht werden.
SQL-Code:
Grüße vom marabu
CREATE TABLE schaeden (
id DOM_PK, name DOM_DISPLAY, anlagen_id DOM_FK ); ALTER TABLE schaeden ADD CONSTRAINT pk_schaeden PRIMARY KEY (id); ALTER TABLE schaeden ADD CONSTRAINT fk_schaeden FOREIGN KEY (anlagen_id) REFERENCES anlagen (id) ON DELETE CASCADE ON UPDATE CASCADE; |
Re: Violation of foreign key constraint mit Delphi/Firebird
Hallo Marabu,
erstmal danke für Deine Antwort. Ich vergaß zu erwähnen, dass ich neben DEFAULT und NULL auch schon CASCADE definiert hatte, da diese Regel Standard bei all meinen anderen Master-/Detailbeziehungen ist. Und auch da bekam ich die Fehlermeldung beim Einfügen eines neuen Detaildatensatzes, dem noch kein Masterdatensatz zugeordnet ist. Meines Erachtens müßte es doch aber irgendwie funktionieren. Wenn ich SET NULL oder SET DEFAULT festlege, wird der Detaildatensatz beim Löschen des Masterdatensatzes doch auch nicht gelöscht, dem Detaildatensatz wird der definierte DEFAULT-Wert oder NULL zugeordnet und die referentielle Integrität bleibt gewahrt. Ich meine, ich könnte nun einen Dummy-Masterdatensatz einfügen und dann wieder löschen, aber das ist doch nicht Sinn und Zweck des Ganzen... Grüße, elliot |
Re: Violation of foreign key constraint mit Delphi/Firebird
Hi Elliot,
vielleicht hätte ich noch die domain Definitionen mitgeben sollen:
SQL-Code:
Beachte, dass der FK bei mir NULL Werte annehmen darf. So erhältst du keine constraint violations. SET DEFAULT ist bei ownership relations grundsätzlich falsch. Mit SET NULL machst du das Löschen einer Anlage, der bereits Schäden zugeordnet wurden, zu einem alltäglichen Fall (use case). Wenn die Anforderungen das hergeben - Okay. Wenn es auf deinem Mist gewachsen ist - schnell ändern oder nochmal nachfragen. Bei meiner Empfehlung von ON DELETE CASCADE gehe ich davon aus, dass Anlagen mit Schäden nicht gelöscht werden dürfen.
CREATE DOMAIN "DOM_PK" AS INTEGER NOT NULL;
CREATE DOMAIN "DOM_FK" AS INTEGER; Das mit dem default master record würde ich nicht machen. Warum solche Krücken, wo dir FB doch die Mittel zu einer semantisch sauberen Lösung bietet? marabu |
Re: Violation of foreign key constraint mit Delphi/Firebird
Hallo Marabu,
nochmal danke für Deine Antwort. Ich habe jetzt wieder alle FK-Rules auf CASCADE gesetzt. Nachdem der Fehler in Tabelle "Schaden" weiterhin auftrat, in einer anderen Tabelle mit gleichen Verknüpfungen aber nicht, habe ich kurzerhand Tabelle "Schaden" gelöscht und neu angelegt und siehe da, nun funktioniert's. Wer weiß, welche Inkonsistenzen o.ä. sich in den Systemtabellen eingeschlichen hatten. Eine Datenbank-Validierung hatte aber vorher keine Fehler aufgedeckt... elliot PS.: Damit könnte der Thread geschlossen werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 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