Je travaille sur une base de données qui suit les fichiers et les dépendances dans les projets. Brièvement, j'ai deux tables principales; la table PROJECTS répertorie les noms de projets 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.Conflit CASCADE et RESTRICT exigences de clé étrangère?
Maintenant, j'ai une table supplémentaire DEPENDENCIES. Chaque enregistrement de la table de dépendances contient deux fichiers, spécifiant que le premier fichier dépend de la seconde. Encore une fois ce sont des clés étrangères, la première est CASCADE (donc si je supprime une entrée de fichier, cet enregistrement est supprimé), mais la seconde est définie sur RESTRICT (donc je ne suis pas autorisé à supprimer une entrée 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 d'entre eux apparaît dans la table DEPENDENCIES, la clé étrangère RESTRICT empêche la suppression (même si cet enregistrement dans la table des dépendances sera supprimé car l'autre colonne est CASCADE). La seule solution de contournement que j'ai consiste à calculer un ordre exact pour supprimer les fichiers afin qu'aucune des contraintes d'enregistrement de dépendance ne soit violée, et supprimer les enregistrements de fichier un à la fois avant d'essayer de supprimer le projet.
Est-il possible de configurer mon schéma de base de données afin qu'une seule suppression SQL de la table des projets cascade correctement 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 ce travail?
J'aime vraiment l'idée de le faire dans un déclencheur plutôt que dans le code de l'application. Je vais essayer et ressemble à ceci sera la réponse pour moi :) – Chris