2011-12-30 8 views
3

Je développe un centre de messages dans un système d'information, et l'utilisateur aujourd'hui Eric a suggéré l'utilisation hierarchyid datatype pour suivre la réponse de message, car l'objectif est de montrer comme une conversation Outlook ou Gmail.Mise à jour SQL Server HierarchyId après insertion déclencheur

Pour simplifier, je l'ai dans ma table de base de données Messages:

MessageId int PK 
ReplyToId int FK null 
Subject varchar 
Body varchar 
Hierarchy hierarchyid 

Lorsqu'un nouveau message est inséré, j'ai un déclencheur pour faire la mise à jour.

J'ai inséré un nouveau message, et la hiérarchie est null, parce que c'est le premier message, et n'est pas une réponse.

Si essayer d'insérer une réponse à ce message, le hierarchyid encore null ... :(

Mon déclencheur:

ALTER TRIGGER [dbo].[trg_UpdateHierarchy] 
    ON [dbo].[Messages] 
    AFTER INSERT 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for trigger here 

    DECLARE @replyId int 
    SELECT @replyId = inserted.ReplyId 
    FROM inserted 
    IF(@replyId IS NULL) 
    BEGIN 
     RETURN 
    END 

    DECLARE @parent hierarchyid 
    SELECT @parent = Hierarchy 
    FROM [Messages] 
    WHERE [Messages].MessageId = @replyId 


    DECLARE @currentHierarchy hierarchyid = @parent.GetDescendant(null, null).ToString() 
    DECLARE @messageId int 
    SELECT @messageId = inserted.MessageId 
     FROM inserted 
    UPDATE [Messages] 
     SET Hierarchy = @currentHierarchy 
     WHERE [Messages].MessageId = @messageId 
END 
GO 

Ce que je fais mal

Une autre point, j'ai lu sur l'index, mais profondeur d'abord ne correspondent pas parce que beaucoup avec une valeur nulle, parce que le premier message d'une conversation a une valeur nulle, et le pain d'abord est le meilleur type d'index pour une meilleure performance ? Ou je peux jeter cet index?

Merci d'avance!

EDIT:

J'ai mis à jour le déclencheur, mais ne pas faire le hierarchyid dans le bon sens.

Maintenant, le déclencheur est:

ALTER TRIGGER [dbo].[trg_UpdateHierarchy] 
    ON [dbo].[Messages] 
    AFTER INSERT 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for trigger here 
    DECLARE @messageId int 
    DECLARE @ParentId int 
    SELECT @messageId = inserted.MessageId, 
      @ParentId = inserted.ParentId 
     FROM inserted 

    IF(@ParentId IS NULL) 
     BEGIN 
      UPDATE [Messages] 
       SET Hierarchy = hierarchyid::GetRoot() 
       WHERE [Messages].MessageId = @messageId 
      RETURN 
     END 
    ELSE 
     BEGIN 
      DECLARE @parent hierarchyid 
      SELECT @parent = Hierarchy 
       FROM [Messages] 
       WHERE [Messages].MessageId = @ParentId 

      DECLARE @lastHierarchy hierarchyid 
      SELECT @lastHierarchy = MAX(Hierarchy) 
       FROM [Messages] 
       WHERE Hierarchy.GetAncestor(1) = @parent 

      UPDATE [Messages] 
       SET Hierarchy = @parent.GetDescendant(@lastHierarchy, NULL) 
       WHERE [Messages].MessageId = @messageId 
     END 
END 

Si j'insérer des messages comme id = 2 a parentId = 1 et id = 3 a parentId = 2 ont cette hiérarchie:
id = 1, hierarchy = \
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\

Le premier et le deuxième enregistrement a la hiérarchie droite, mais suivant pas ... :(

un indice?

Répondre

1

En fait, est une implémentation correcte de la hiérarchie. Cependant, il a des limites avec des inserts traités par lots, mais c'est une autre question .. En outre, il peut être judicieux de début tous les « racines » avec \x, ou un niveau de profondeur, de sorte que les conversations ne partagent pas un arbre parent.

Dans tous les cas, insérez un 2ème nœud avec id = 4, parentId = 2, puis il devrait ressembler à hierarchy = \1\2 (il est sur le même niveau de hiérarchie, mais après \1\1).

Les valeurs indiquées sous la forme hierarchy « string » ne doivent se rapporter à la valeur parentId!

Questions connexes