在插入触发器之后更新SQL Server HierarchyId

时间:2011-12-30 19:32:52

标签: sql-server triggers hierarchy hierarchyid

我正在信息系统中开发一个消息中心,今天用户Eric建议使用hierarchyid数据类型来跟踪消息回复,因为目标是显示为Outlook或Gmail对话。

为了简化,我在我的数据库表中消息:

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

插入新邮件时,我会触发更新。

我插入了一条新消息,层次结构为空,因为它是第一条消息,而不是回复。

如果尝试插入对该消息的回复,则hierarchyid仍为null ... :(

我的触发器:

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 

我做错了什么?

另一点,我已经读过关于索引的内容,但深度优先不适合因为有许多空值,因为来自会话的第一条消息具有空值,而bread-first是最好的索引类型有更好的表现?或者我可以丢弃这个索引?

提前致谢!

编辑:

我已更新了触发器,但没有以正确的方式执行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 = 2parentId = 1的消息,而id = 3 parentId = 2id = 1, hierarchy = \
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\
这样的层次结构:
{{1}}

第一个和第二个记录具有正确的层次结构,但下一个记录没有... :(

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

实际上一个正确的层次结构实现。但是,它对批量插入有局限性,但这是另一个问题..同样,开始所有“根”与\x或一个深度一样,这样的对话可能是有意义的。所以对话不要共享父树。

在任何情况下,插入带有id = 4, parentId = 2的第二个节点,它应该看起来像hierarchy = \1\2(它位于同一层次结构级别,但在\1\1之后)。

hierarchy“字符串”表单中显示的值不需要与parentId值相关联!