Question

Je travaille sur une base de données qui suit les fichiers et les dépendances dans les projets. En bref, j'ai deux tables principales; la table PROJECTS répertorie les noms de projet et d'autres propriétés, la table FILES répertorie les fichiers. Chaque entrée de fichier pointe vers un projet en tant que clé étrangère définie sur CASCADE. Par conséquent, si je supprime un enregistrement de projet de la base de données, tous les enregistrements de fichier disparaissent également. Jusqu'ici, tout va bien.

J'ai maintenant une table supplémentaire DEPENDENCIES. Chaque enregistrement de la table de dépendance est constitué de deux fichiers, spécifiant que le premier fichier dépend du second. Encore une fois, ce sont des clés étrangères, le premier est défini sur CASCADE (donc si je supprime une entrée de fichier, cet enregistrement est supprimé), mais le second est défini sur RESTRICT (je ne suis donc pas autorisé à supprimer une entrée de fichier si d'autres fichiers dépendent dessus). Encore une fois, tout semble bien.

Malheureusement, il semble que je ne puisse plus supprimer un projet avec une seule instruction de suppression SQL! La suppression tente de supprimer en cascade les fichiers, mais si l'un de ces éléments apparaît dans la table DEPENDENCIES, la clé étrangère RESTRICT empêche la suppression (même si cet enregistrement de la table de dépendances sera supprimé car l'autre colonne est CASCADE). La seule solution que je dispose consiste à calculer un ordre exact pour supprimer les fichiers afin qu'aucune des contraintes d'enregistrement de dépendance ne soit violée, et supprimez les enregistrements de fichier l'un après l'autre avant de tenter de supprimer le projet.

Existe-t-il un moyen de configurer mon schéma de base de données afin qu'une seule suppression SQL de la table des projets mette correctement en cascade les autres suppressions? J'utilise Firebird 2.1, mais je ne sais pas si cela fait une différence - il semble qu'il devrait y avoir un moyen de faire en sorte que cela fonctionne?

Était-ce utile?

La solution

Vous ne pouvez pas contrôler l'ordre de suppression par le biais d'une clé étrangère en cascade, mais vous pouvez éventuellement concevoir un déclencheur sur PROJECTS pour supprimer les lignes de FILES appartenant à ce projet et également répertoriées dans <= > dépendant d'autres DEPENDENCIES. Faites-en un déclencheur BEFORE DELETE, il devrait donc être exécuté avant les effets en cascade.

Quelque chose comme ça:

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

Ainsi, lorsque vous supprimez un projet, tous les " enfants " fichiers d’un projet qui dépendent d’autres fichiers, ce qui entraîne la suppression de lignes dans <=>, de sorte que tous les fichiers restants sont exempts de dépendances. Votre suppression du projet peut maintenant en cascade supprimer ces fichiers.

Je n'ai pas testé cela et ma syntaxe Firebird est peut-être rouillée, mais peut-être que ça vous aidera à démarrer.

Évidemment, testez ceci sur une copie de vos données, pas sur les données en direct!

Autres conseils

Le système prend-il en charge les contraintes différées, dans lesquelles le contrôle de contrainte peut être différé jusqu'à un point de validation?

Peut-être que c'est juste un truc d'Oracle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top