FK-Beziehung durch Trigger ersetzen

Hallo,

aus einem begründeten Anlass möchte eine FK-Beziehung als Trigger nachprogrammieren. Dazu sollte der Trigger aus Tabelle A bei einer DELETE-Operation gleichzeitig auch die entsprechenden Einträge aus Tabelle B löschen:

Trigger in Tabelle A: DELETE FROM B WHERE B.id = OLD.ID;

Leider scheint diese Anweisung einfach ignoriert zu werden. Hat jemand eine Ahnung warum?

Gruß

Da meine Glaskugel grad zur Reparatur ist, kann ich da ohne konkrete Definition des Triggers wenig bis nichts als Ursache sehen.

Davon abgesehen: Warum machst Du nicht einfach eine FK-Beziehung, wenn Du diese benötigst?

Andreas

Hallo nochmal…

mittlerweile habe ich mich umentschieden und nun doch eine normale Fremdschlüsselbeziehung angewandt. Jedoch will es diesmal nicht funktionieren. Obwohl mit absoluter Sicherheit gesagt werden kann, dass das referenzierte Element vorhanden ist, weigert sich PG den Datensatz einzufügen. Es erscheint die Fehlermeldung:

ERROR: insert or update on table “tab1” violates foreign key constraint “tab1_ID_fkey”
SQL Status:23503
Detail:Key (ID)=(TH08) is not present in table “tab2”.

Kann es für eine derartige Fehlermeldung noch andere Ursachen geben? Wie gesagt, die ID, welche in tab1 eingefügt werden soll, ist auf jeden Fall auch in tab2 enthalten.

Die Constraint-Definition:
CONSTRAINT “tab1_ID_fkey” FOREIGN KEY (“ID”)
REFERENCES tab2 (“ID”) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE


Danke! benwen

Zeig doch mal den konkreten Query, die Ausgabe der Fehlermeldung und einen Select, in dem man das Ergebnis in der anderen Tabelle sieht …

sorry, aber da die Vorgehensweise die gleiche ist, wie ich sie immer zuvor angewandt habe, kann es eigentlich nicht daran liegen, dass irgendein Befehl falsch eingegeben wurde. Ich arbeite mit PGadmin III, vlt. liegt es daran?
Gerade habe ich die gleiche Situation in einer anderen PG-Datenbank nachgebaut und dort funktioniert es komischerweise.

Kann es sein, dass sich das Problem mit dem kompletten Neuaufbau der Datenbank lösen lässt? Und falls ja, gibt es eine effiziente Möglichkeit, alle zur DB gehörenden CREATE-Anweisungen anzeigen zu lassen?

Besten Dank, benwen

Also bis auf du weiss niemand, was bisher das konkrete Problem ist noch kennen wir eine Fehlermeldung oder eine konkrete(!) Fehlerbeschreibung.

Wie soll dir dabei geholfen werden?

Ich dachte ich hätte das Problem ausreichend beschrieben. Die genaue Fehlermeldung steht in meinem 2. Post.

Nochmal (etwas konkreter) zum Fehler:
Ich habe eine FK-Beziehung zwischen zwei Tabellen aufgebaut nach dem klassischen Schema:

Tabelle1:

CREATE TABLE base.vertex
(
– Vererbt: “elemID” text NOT NULL,
– Vererbt: “trackID” text NOT NULL,
“vertexID” text NOT NULL,
(weitere Attribute…)

CONSTRAINT vertex_pkey PRIMARY KEY (“elemID”),
CONSTRAINT “nodes_trackID_fkey” FOREIGN KEY (“trackID”)
REFERENCES base.track (“trackID”) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT “vertex_vertexID_key” UNIQUE (“vertexID”)
) INHERITS (base.element)
WITHOUT OIDS;
ALTER TABLE base.vertex OWNER TO “admin”;

Tabelle2:

CREATE TABLE base.vertex_edge
(
“edgeID” text NOT NULL,
“vertexID” text NOT NULL,
CONSTRAINT vertex_edge_pkey PRIMARY KEY (“edgeID”),
CONSTRAINT “vertex_edge_vertexID_fkey” FOREIGN KEY (“vertexID”)
REFERENCES base.vertex (“vertexID”) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITHOUT OIDS;
ALTER TABLE base.vertex_edge OWNER TO “admin”;

Jetzt wende ich folgenden Befehl an:

INSERT INTO base.vertex_edge( “edgeID”, “vertexID”) VALUES (‘bsp’, ‘id1’);

Ich bin mir wie gesagt 100 %ig sicher, dass ‘id1’ in der referenzierten Tabelle ‘vertex’ vorhanden ist.
Ich hoffe die Beschreibung genügt nun.

Da bin ich mir nicht so sicher. Bzw, ich bin mir wie du sicher, dass ‘id1’ in dieser Tabelle vorhanden ist, aber ich glaube, du hast woanders einen Fehler.

Zeig uns doch mal bitte den Output von ‘\df vertex_edge’.


CONSTRAINT “vertex_edge_vertexID_fkey” FOREIGN KEY (“vertexID”)

Das verweist imho auf die aktuelle Tabelle, nicht auf eine andere.

Danke für deine Antwort. Das Ergebnis von \df vertex_edge liefert folgendes:

MYDB-# \df vertex_edge
Liste der Funktionen
Schema | Name | Ergebnisdatentyp | Argumentdatentypen
--------±-----±-----------------±-------------------
(0 Zeilen)

Warum sollte der Ausdruck:
CONSTRAINT “vertex_edge_vertexID_fkey” FOREIGN KEY (“vertexID”)

auf eine andere Tabelle verweisen? Der Name des FK wurde von PGAdmin vergeben…aber der ist ja auch egal oder?

Gruß

Ach Müscht, mein Fehler. ‘\df’ ist falsch, das listet Funktionen. Nur ‘\d’ müsste das sein, und dann den Tabellennamen dahinter.

MYDB=# \d base.vertex_edge
Tabelle »base.vertex_edge«
Spalte | Typ | Attribute
----------±-----±----------
edgeID | text | not null
vertexID | text | not null
Indexe:
»vertex_edge_pkey« PRIMARY KEY, btree (“edgeID”)
Fremdschlüssel-Constraints:
»vertex_edge_vertexID_fkey« FOREIGN KEY (“vertexID”) REFERENCES base.vertex(
“vertexID”)

Gut, passt soweit. Die Struktur sah in der ersten Ausgabe etwas komisch aus.

Kannst du uns jetzt noch die Inhalte aus der ersten Tabelle pasten, die du referenzierst?

Das funktioniert (leider) nicht so, wie man sich das vorstellt. Lese Dir bitte PostgreSQL: Documentation: Manuals: PostgreSQL 8.1: Inheritance durch. Vermutlich findest Du die Ursache für Dein Problem dort erklärt.

Andreas

Hallo nochmal und danke für die Hilfe,

mittlerweile fand ich heraus, dass die Ursache tatsächlich in der Vererbung zu finden ist. Letztendlich hat die Vererbung in PG kaum etwas mit der Funktionalität einer Klassenhierachie der objektorientierten Programmierung zu tun. Ich habe jetzt ein neues Datenbankschema entworfen, ohne jegliche Vererbung. Auf diese Weise wird das Ganze wesentlich transparenter und man weiß was passiert.

Mir fällt gerade kein Bereich ein, in der die Vererbung so richtig Sinn macht. Zumindest nicht, wenn die Datenbank wirklich konsistent sein soll. Also lieber auf die herkömmlichen Assoziationen setzen, da gibts keine Probleme.

Gruß
benwen