[Trigger] Trigger cascade table hiérarchique
SOUS SQL SERVER 2000
Salut à tous :)
Petit problème du dimanche après midi :
Je travaille sur une table hiérarchique T1 (qui point sur elle même). A chaque enregistrement de la table T1 peut correspondre un ou plusieurs enregistrements d'une table de jointure J1.
Code:
1 2 3 4 5
|
T1 J1
/Code------------------------ Code
\FK_T1_Code \--FK_T1_Code
FK_T2 |
Code de T1 est référencé dans J1 par FK_T1_Code
Code de T1 est référencé dans T1 par FK_T1_Code
Lorsque je veux supprimer une enreg de T1, je dois d'une part supprimer les enregistrements correspondant de la jointure (jusque là rien de violent) et d'autre part tous les enregistrements fils de L'enregistrement de T1 en cours de suppression et bien entendu tous les enregs de la jointure correspondant.
Cela donne une sorte de trigger récursif
Je sais faire en procédure stockée mais je trouve que ça serait beaucoup plus propre en trigger, ce qui m'amène à vous poser la question suivante :
Peut-on créer des triggers récursif ? Si oui, doit-on séparer la suppression des fils de la suppression des enregistrements des jointures ?
D'avance merci
Bien à vous
Laurent
LA PROC STOCK Que j'aimerais faire en Triggers
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
ALTER PROCEDURE SP_R
(
@Parent int
)
AS
/* Procédure récursive
Creation de #TMP_R Table temporaire de récursion contenant les codes de la descendance
*/
declare @Code int
declare @lvl int
if @@NESTLEVEL=1
BEGIN
CREATE TABLE #TMP_R (
Code int,
Niv int
)
-- On enregistre le 1er code dans la table temporaire
INSERT INTO #TMP_R (Code,Niv) VALUES (@ParentMenu,0)
END
PRINT @ParentMenu
DECLARE C CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY FOR
SELECT Code
FROM T1
WHERE FK_T1_Code = @ParentMenu
OPEN C
FETCH NEXT FROM C INTO
@Code
WHILE @@FETCH_STATUS = 0
BEGIN
-- On enregistre les code des descendants dans la table temporaire
INSERT INTO #TMP_R
(Code,Niv)
VALUES
(@Code,@@NESTLEVEL)
exec SP_R @Code
FETCH NEXT FROM C INTO
@Code
END
CLOSE C
DEALLOCATE C
if @@NESTLEVEL=1
BEGIN
-- On est ici après être remonté de la récursion
-- Tres important je trie par niveau à l'envers pour ne pas obtenir d'erreur de violation d'intégrité
DECLARE C CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY FOR
SELECT Code,Niv FROM #TMP_R ORDER BY Niv DESC
OPEN C
FETCH NEXT FROM C INTO
@Code,@lvl
WHILE @@FETCH_STATUS = 0
BEGIN
--Je supprime d'abord les éléments de la jointure
DELETE FROM J1 WHERE FK_T1_Code = @Code
--Je supprime ensuite le decendant qui à ce stade n'a plus de décendant
DELETE FROM T1 WHERE Code = @Code
FETCH NEXT FROM C INTO
@Code,@lvl
END
CLOSE C
DEALLOCATE C
--Je détruis la table temporaire de récursion
DROP TABLE #TMP_R
END
RETURN |