2011-12-30 4 views
3

Я разрабатываю центр сообщений в информационной системе, и сегодня пользователь Eric предложил использовать тип данных hierarchyid для отслеживания ответа на сообщение, поскольку цель состоит в том, чтобы показать как сеанс Outlook или Gmail.Обновление иерархии SQL Server после запуска вставки

Для упрощения, я имею в моей таблице базы данных сообщений:

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

Когда новое сообщение вставляется, Я триггер, чтобы сделать обновление.

Я вставил новое сообщение, и иерархия имеет значение null, потому что это первое сообщение и не является ответом.

Если попытаться вставить ответ на это сообщение, 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 

Что я делаю неправильно

Другой point, я читал об этом индексе, но сначала он не подходит, потому что у него много значений с нулевым значением, потому что первое сообщение из разговора имеет нулевое значение, а хлеб - это лучший тип индекса, который имеет лучшую производительность ? Или я могу отказаться от этого индекса?

Заранее благодарен!

EDIT:

Я обновил курок, но не делают 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!

Смежные вопросы