J'ai une table de nœuds avec (NodeId, NodeName) et une table de structure (ParentNodeId, ChildNodeId). Comment puis-je écrire un déclencheur qui vérifie si une instruction de mise à jour ou de suppression d'insert peut provoquer une relation infinie?Déclenchement pour empêcher une boucle infinie dans un arbre SQL
3
A
Répondre
1
Vous devrez vérifier récursivement la condition de dépendance circulaire dans laquelle le parent ne devient pas un enfant de son propre enfant, directement ou indirectement.
Dans SQL Server 2005, vous pouvez écrire un CTE récursif pour le même. Un exemple -
WITH [RecursiveCTE]([Id], [ParentAccountId]) AS
(
SELECT
[Id],
[ParentAccountId]
FROM [Structure]
WHERE [Id] = @Id
UNION ALL
SELECT
S.[Id],
S.[ParentAccountId]
FROM [Structure] S INNER JOIN [RecursiveCTE] RCTE ON S.[ParentAccountId] = RCTE.[Id]
)
SELECT * FROM [RecursiveCTE]
3
Voici ma solution, et jusqu'à présent cela fonctionne comme prévu.
CREATE TRIGGER [dbo].[CheckNodeDependence] ON [dbo].[ObjectTrees]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE @CTable TABLE(ChildId INT NOT NULL,
ParentId INT NOT NULL,
[Level] INT NOT NULL,
RowId INT NOT NULL)
DECLARE @Level INT
SET @Level = 1
DECLARE @rows_affected INT
SET @rows_affected = 1
INSERT INTO @CTable
SELECT ObjectId, ParentId, 1, ObjectId FROM INSERTED
WHILE @rows_affected > 0
BEGIN
SET @Level = @Level + 1
INSERT INTO @CTable
SELECT T.ObjectId, T.ParentId, @Level, C.RowId
FROM ObjectTrees T
INNER JOIN @CTable C ON T.ParentId = C.ChildId
AND C.Level = @Level - 1
SET @rows_affected = @@rowcount
IF EXISTS(
SELECT * FROM @CTable B
INNER JOIN @CTable V ON B.level = 1
AND V.Level > 1
AND V.RowId = B.RowId
AND V.ChildId = B.RowId)
BEGIN
DECLARE @error_message VARCHAR(200)
SET @error_message = 'Operation would cause illegal circular reference in tree structure, level = ' + CAST(@Level AS VARCHAR(30))
RAISERROR(@error_message,16,1)
ROLLBACK TRANSACTION
RETURN
END
END
END
GO
Questions connexes
- 1. Boucle infinie dans FreeBSD
- 2. Comment détecter une boucle infinie dans un appel récursif?
- 3. MFC OnEnChange fonction de gestionnaire - boucle infinie
- 4. Mémoire insuffisante - Boucle infinie - Cadre ASP.NET AJAX
- 5. Expressions régulières Javascript - exec boucle infinie
- 6. jQuery Non le sélecteur provoque une boucle infinie
- 7. Pourquoi mon regex Perl provoque-t-il une boucle infinie?
- 8. Une requête pour résumer des données dans un sous-arbre?
- 9. MS SQL dans une boucle
- 10. Comment puis-je contourner une erreur d'arrondi qui provoque une boucle infinie dans Perl's Statistics :: Descriptive?
- 11. Réutilisation de SocketAsyncEventArgs avec ReceiveAsync en boucle infinie
- 12. Boucle infinie en traversant XML en Actionscript 3
- 13. Est-il possible d'utiliser nanosleep dans une boucle infinie avec select()?
- 14. Java newbie: boucle infinie recherche de texte spécifique dans un fichier
- 15. Syntaxe d'une boucle infinie Bash à ligne unique
- 16. Pourquoi la journalisation se déroule-t-elle dans une boucle infinie?
- 17. Dépannage d'une redirection infinie dans une application Web
- 18. Winforms .NET: empêcher le déclenchement par clic de bouton pour une zone de texte multiligne sur un formulaire activé "AcceptButton"?
- 19. Déclenchement d'une méthode pour exécution dans un thread séparé
- 20. boucle dans trigger SQL Server
- 21. Comment récupérer le chemin d'un nœud dans un arbre - efficace (lié au poste 'analyser une table plate dans un arbre?)
- 22. Désactiver Activer le serveur SQL de déclenchement
- 23. Comment faire une boucle SQL pour la date?
- 24. Qu'est-ce qu'une arborescence Splay, un arbre rouge-noir, un arbre AVL, un arbre B et un arbre-T?
- 25. en utilisant une boucle dans un gabarit
- 26. While-clause dans T-SQL qui boucle pour toujours
- 27. stop sql insert dans une boucle for ou while
- 28. Marcher dans un arbre XML en C#
- 29. Des trous de boucle logique dans cette idée pour empêcher Cross Site Request Forgery?
- 30. Lignes en boucle dans SQL Server
mais une fois trouvé, quel est le meilleur moyen de provoquer un échec d'insertion/mise à jour en utilisant un déclencheur? – MatBailie
Selon la plate-forme. Dans Oracle, vous lanceriez une exception, avec autant d'informations utiles que possible dans le texte. Mais vraiment, cela dépend de l'application, n'est-ce pas? –
Oui. Cela dépend de l'application que vous utilisez. Dans SQL Server, vous lancerez également une exception pour arrêter l'insertion. Ou vous pouvez utiliser les déclencheurs Au lieu de et ne rien faire. – Kirtan