Frage

Ich arbeite an einer Datenbank, die Dateien und Abhängigkeiten in Projekten verfolgt. Kurz gesagt, ich habe zwei Haupttabellen; Die Projekte Tabelle listet Namen und andere Eigenschaften projizieren, listet die Dateien Tabellendateien. Jeder Dateieintrag verweist auf ein Projekt als Fremdschlüssel zu CASCADE eingestellt, so dass, wenn ich ein Projekt Datensatz aus der Datenbank löschen, werden alle Dateieinträge verschwinden auch. So weit, so gut.

Jetzt habe ich einen zusätzlichen DEPENDENCIES Tisch. Jeder Datensatz in der Abhängigkeitstabelle ist zwei Dateien, die Angabe, dass die erste Datei auf dem zweiten abhängt. Wieder sind diese Fremdschlüssel wird die erste auf CASCADE eingestellt (also wenn ich eine Datei Eintrag löschen, dieser Datensatz gelöscht wird), aber der zweite Satz ist zu beschränken (so einen Dateieintrag zu löschen, wenn alle anderen Dateien, die ich bin nicht abhängig erlaubt darauf). Auch hier scheint alles gut.

Leider scheint es, ich kann nicht mehr ein Projekt mit einem einzigen SQL-Anweisung löschen löschen! Der Lösch versucht, die Dateien in Kaskade löschen, aber wenn irgendetwas davon in der DEPENDENCIES Tabelle angezeigt, die einstelle Fremdschlüssel den Lösch verhindert (obwohl dieser Datensatz in der Tabelle Abhängigkeiten entfernt werden, da die andere Säule CASCADE ist). Die einzige Abhilfe, die ich habe, ist eine genaue Reihenfolge zu berechnen, die Dateien so dass keiner der Abhängigkeit Rekord Einschränkungen verletzt werden zu löschen und entfernen Sie eine Datei der Aufzeichnungen zu einem Zeitpunkt, bevor das Projekt zu entfernen.

Gibt es eine Möglichkeit, meine Datenbankschema einzurichten so dass eine einzelne SQL aus der Tabelle Projekte löschen, werden die anderen Löschungen richtig kaskadieren? Ich bin mit Firebird 2.1, aber ich weiß nicht, ob das einen Unterschied macht - es scheint, wie es sollte ein Weg, um diese Arbeit zu machen

War es hilfreich?

Lösung

Sie können nicht die Reihenfolge der Löschung durch eine Kaskadierung von Fremdschlüssel steuern, aber Sie können einen Trigger auf PROJECTS entwerfen können, Zeilen in FILES zu löschen, die zu diesem Projekt gehören und auch in DEPENDENCIES als abhängig von anderen FILES aufgelistet . Machen Sie es einen BEFORE DELETE Trigger, also sollte es vor den Kaskadeneffekte auszuführen.

So etwas wie folgt aus:

CREATE TRIGGER Del_Child_Files FOR PROJECTS
BEFORE INSERT
AS BEGIN
  FOR SELECT F.FILE_ID FROM FILES F JOIN DEPENDENCIES D 
      ON F.FILE_ID = D.CHILD_ID
    WHERE F.PROJECT_ID = OLD.PROJECT_ID
    INTO :file_id
  DO
    DELETE FROM FILES WHERE FILE_ID = :file_id;
  DONE
END
So

Wenn Sie ein Projekt löschen, dies löscht alle „Kind“ Dateien eines Projektes, das auf anderen Dateien abhängig ist, und diese Kaskaden Reihen in DEPENDENCIES zu löschen, so dass alle verbleibenden Dateien frei von Abhängigkeiten sind. Ihre Löschung des Projekts können nun kaskadieren, diese Dateien zu löschen.

Ich habe nicht getestet und meine Firebird Syntax rostig sein, aber vielleicht wird es Ihnen den Einstieg.

Offensichtlich bitte testen diese auf einer Kopie Ihrer Daten, nicht die Live-Daten!

Andere Tipps

Unterstützt das System latente Zwänge, in denen die Bedingungsprüfung, bis eine COMMIT-Punkt verschoben werden kann?

Vielleicht ist das nur eine Oracle-Sache aber.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top