【问题标题】:Update SQL Server HierarchyId in after insert trigger在插入触发器后更新 SQL Server HierarchyId
【发布时间】:2011-12-30 19:32:51
【问题描述】:

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

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

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 = 3parentId = 2 有这个层次结构:
id = 1, hierarchy = \
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\

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

有什么线索吗?

【问题讨论】:

    标签: sql-server triggers hierarchy hierarchyid


    【解决方案1】:

    实际上一种正确的层次结构实现。但是,它对批量插入有限制,但这是另一个问题 .. 而且,start 所有“根”都使用\x 或一层深度可能是有意义的,因此对话不会共享父树。

    无论如何,插入带有id = 4, parentId = 2 的第二个节点,那么它应该看起来像hierarchy = \1\2(它在同一层次结构级别上,但在\1\1 之后)。

    hierarchy“字符串”形式中显示的值不需要parentId值相关!

    【讨论】:

      猜你喜欢
      • 2018-05-26
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多