2010-02-02 2 views
0

Je crée un composant de blog pour le site Web d'un client et les données me posent un problème. J'ai une simple table de "contenu" qui contient le contenu d'une entrée de blog. Je réutilise cette table pour les commentaires sur les entrées de blog car les champs sont tous les mêmes.Stockage et suppression récursive de données dans SQL Server

J'ai ajouté un ParentID à la table de contenu afin que je puisse lier des commentaires à leur élément de contenu parent. Afin d'assurer que je ne reçois pas des éléments de contenu zombied J'ai ajouté un déclencheur pour supprimer tous les éléments de contenu enfant lorsqu'un élément de contenu est supprimé:

delete from content where ParentID in (select ID from deleted) 

Cependant, lorsque je supprime des éléments de contenu qui n'ont même pas tous les éléments de contenu des enfants que je reçois une erreur de SQL Server (2008):

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32). 

le déclencheur doit tirer une fois pour le contenu supprimé, mais ne devrait pas être appelé à nouveau si le contenu n'a pas d'enfant? Est-ce que quelqu'un sait pourquoi je reçois cette erreur?

TIA

+0

Tout le respect dû, et il ne répond pas à votre question directement, mais ayant deux tables séparées serait une meilleure conception. Plus clair, plus simple et fonctionnerait probablement mieux pour la plupart des types d'interaction avec les bases de données. – onupdatecascade

Répondre

0

Vous feriez mieux d'utiliser la solution ensembliste pour que:

WITH h AS 
     (
     SELECT id 
     FROM content 
     WHERE id = @row_to_delete 
     UNION ALL 
     SELECT c.id 
     FROM h 
     JOIN content c 
     ON  c.parentID = h.id 
     ) 
DELETE 
FROM content 
WHERE id IN 
     (
     SELECT id 
     FROM h 
     ) 

Pour vous assurer qu'aucune ligne orphelins ne sont jamais laissés, créer un faux ancêtre commun avec hardcoded id et parent égale à ce id:

INSERT 
INTO content (id, parentid) 
VALUES (0, 0) 

ALTER TABLE content 
ADD CONSTRAINT fk_content_parent_self 
FOREIGN KEY (parentId) 
REFERENCES content (id) 
0

Modifier le déclencheur pour n'effectuer la supprimer si les lignes existent

DECLARE @ID int 
SELECT @ID = TOP 1 ID from content where ParentID in (select ID from deleted) 
IF (@ID IS NOT NULL) 
BEGIN 
    delete from content where ParentID in (select ID from deleted) 
END 
+0

merci Matt, je suis arrivé à une conclusion similaire en utilisant IF EXISTS - typique, je trouve toujours une solution dès que je pose la question !! Merci pour la réponse cependant, appréciez-le. – Alan

+0

Pas de soucis, ça arrive tout le temps - Je pense que l'écriture de votre question vous fait réfléchir plus clairement ... –

Questions connexes