2009-09-21 5 views
11

En passant par un projet que j'ai repris, et du côté de la base de données, j'ai remarqué que les programmeurs précédents ont écrit un tas de déclencheurs pour supprimer les enregistrements enfants. Le fait est que ces enregistrements ont déjà une relation de clé étrangère avec l'enregistrement parent que je supprime. Les déclencheurs de suppression ne sont rien d'autre que des instructions de suppression simples pour les enregistrements enfants.Cascade sur Supprimer ou utiliser les déclencheurs?

Y a-t-il un avantage à écrire un déclencheur pour supprimer les enregistrements enfants, ou puis-je simplement le changer pour cascade lors de la suppression et ça va? Im utilisant MSSQL 2008.

Répondre

15

CASCADE DELETE dans MSSQL Server ne peut être appliqué qu'en cascade à une seule table. Si vous avez deux tables avec des relations de clé étrangère dans une table de dimension, vous ne pouvez supprimer en cascade que l'une d'entre elles. (Ceci permet d'éviter la suppression en cascade de plusieurs chemins et la création de conflits, tout comme C++ permet l'héritage multiple mais C# n'autorise qu'un seul héritage)

Dans ce cas, vous devez utiliser des déclencheurs ou gérer spécifiquement le cas dans votre code.

Pour cette raison, j'ai vu beaucoup de gens opter pour l'utilisation de déclencheurs dans tous les cas. Même lorsqu'il n'y a qu'une seule table étrangère. Cela garantit la cohérence et permet aux utilisateurs de savoir ce qu'il faut rechercher lors de la maintenance de la base de données.

Si l'on pouvait mettre en cascade une suppression à plus d'un tableau, je dirais que ce serait l'option la plus préférable. Cette limitation, cependant, trouble les eaux et je suis actuellement plus en faveur des déclencheurs possédant tous ces comportements. L'utilisation de déclencheurs pour les suppressions et les mises à jour en cascade n'est que minime en termes de codage, mais permet des pratiques standard qui sont vraiment génériques.

EDIT:

Vous pouvez déplacer la « réponse acceptée » à quelqu'un d'autre, j'ai travaillé que j'avais tort Abot ci-dessus.

Vous pouvez avoir plusieurs tables de faits sur ON SUPPRIMER CASCADE Contraintes de clé étrangère à un tableau de dimensions signet. Ce que vous ne pouvez pas faire est d'avoir une table de faits ayant des contraintes de clé étrangère DELETE CASCADE à plusieurs tables de dimension.

Ainsi, par exemple ...
- Tableau des dimensions [personne] (id INT IDENTITY,)
- Table Dimension [examen] (id INT IDENTITY,)
- Table Face [Exam_Score] (person_id INT, exam_id INT, score INT)

Si la personne ou l'examen est supprimé, vous souhaitez que les enregistrements Exam_Score associés soient également supprimés.

Ceci n'est pas possible en utilisant ON DELETE CASCADE dans MS SQL Server, d'où la nécessité de triggers.

(Toutes mes excuses à Mehrdad qui ont essayé d'expliquer cela à moi, mais j'échapperaient complètement son point.)

+0

Merci Dems, cela ressemble exactement pourquoi ils ont mis les déclencheurs en place –

+0

+1 - Je n'ai pas pensé à cette situation . –

10

Restez à l'écart des déclencheurs inutiles.

Allez avec ON DELETE CASCADE si c'est tout ce que vous devez faire.

+0

Ils ne sont pas toujours inutiles. Vous ne pouvez pas, par exemple, mettre en cascade dlete à plus d'une table étrangère. – MatBailie

+0

Je n'ai pas dit qu'ils sont inutiles. J'ai dit que vous devriez utiliser 'ON DELETE CASCADE' si cela convient à votre problème (je pense que la situation de l'OP est satisfaite par' CASCADE'). BTW, que voulez-vous dire "à plus d'une table étrangère" Je suis sûr que "ON DELETE CASCADE" fonctionne de manière hiérarchique aussi. Cependant, il ne prend pas en charge les références directes et indirectes provenant d'une seule table. –

+0

Non, MS SQL Server n'autorise pas la suppression d'une clé primaire ou d'une contrainte unique en cascade vers plusieurs tables. Essayez de le configurer et vous obtenez un message d'erreur. La suppression en cascade ne fonctionne que d'une table de dimension à une table de faits. Cela ne fonctionne pas d'une table de dimension à plusieurs tables de faits. – MatBailie

1

J'utiliserais cascade lors de la suppression, mais uniquement si vous voulez vraiment supprimer l'enfant si le parent est supprimé.

Si vous avez une logique conditionnelle (je ne supprime l'enfant que s'il est supprimé un dimanche), utilisez un déclencheur.

Je voudrais juste le changer en cascade on delete, sur un système de développement, puis exécutez mes tests unitaires et assurez-vous que rien ne casse.

1

Je suis presque d'accord avec Dems ici que j'utilise ON DELETE CASCADE (et ON UPDATE CASCADE pour cette matière) actions référentielles la mesure du possible et seulement recourir à des déclencheurs si nécessaire. J'envisagerais également de révoquer les permissions des tables et de forcer l'utilisation de procédures stockées 'helper' pour les suppressions et les mises à jour. Appelez-moi optimiste, mais je crois a) que mon code survivra au portage vers une future version de MS SQL Server et b) l'équipe SQL Server va bientôt contourner le problème de la limitation du 'chemin en cascade', à quel point je vais remplacer les déclencheurs par des actions référentielles en cascade :)

Questions connexes