2011-12-30 123 views
3

我正在信息系統中開發消息中心,今天用戶Eric建議使用hierarchyid數據類型來跟蹤消息答覆,因爲目標是顯示爲Outlook或Gmail對話。在插入觸發器後更新SQL Server HierarchyId

爲了簡化,我在我的數據庫表的消息:

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

當插入一個新的消息,我有一個觸發器,完成更新。

我插入了一條新消息,並且層次結構爲空,因爲是第一條消息,而不是回覆。

如果試圖插入到該消息的回覆中,HIERARCHYID還是空... :(

我的觸發器:

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 

我做錯了什麼

另一個點,我已經閱讀了關於索引,但深度優先不適合,因爲有很多與空值,因爲對話的第一個消息有空值,麪包優先是最好的索引類型有更好的性能?或者我可以放棄這個索引?

在此先感謝!

編輯:

我已經更新了扳機,但在正確的方式不做hierarchyid

現在的觸發是:

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 

如果我插入像id = 2消息有parentId = 1,並id = 3具有parentId = 2有這樣的層次:
id = 1, hierarchy = \
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\

第一和第二條記錄有正確的層次結構,但下一個沒有... :(

任何線索?

回答

1

那實際上一個正確的層次實現。然而,它對批量插入有限制,但這是另一個問題。另外,它可能對開始所有「根」具有\x或深度一級,所以對話不共享父樹。

在任何情況下,插入第二個節點與id = 4, parentId = 2,那麼它應該看起來像hierarchy = \1\2(它在同一層次上,但在\1\1之後)。

hierarchy「字符串」表中顯示的值不需要需要涉及parentId值!