自动生成层次值(Generate Hierarchy value automatically)

2019-09-19 05:38发布

我有一个树表列IDParentIDHierarchy ,并希望产生Hierarchy依赖的列值ParentID 。 为此,我使用触发器。 这样做存在更好的方法来产生层次列值?

ALTER TRIGGER [TR_MyTable_BeforInsert] ON [MyTable]
INSTEAD OF INSERT
AS BEGIN
SET NOCOUNT ON;
Declare @Name NVarChar(100),
        @ParentID Int

Declare DACategory Cursor For
Select  A.Name, A.ParentID
From    Inserted A
OPEN    DACategory
FETCH NEXT FROM DACategory INTO @Name, @ParentID
While @@FETCH_STATUS=0 Begin

    Insert Into MyTable (Name, ParentID, Hierarchy)
    Values (@Name, @ParentID, dbo.F_MyTableGetHID(NULL, @ParentID))

    FETCH NEXT FROM DACategory INTO @Name, @ParentID
End
Close   DACategory
Deallocate DACategory
END

功能:

ALTER FUNCTION [F_MyTableGetHID]
(
    @ID int,
    @ParentID int
)
RETURNS HierarchyID

AS BEGIN
    Declare @RootHID HierarchyID, 
            @LastHID HierarchyID

    IF (@ParentID IS NULL)Begin
        Set @RootHID = HierarchyID::GetRoot()
        Select @LastHID = Max(Hierarchy) From MyTable Where ParentID IS NULL
    End Else Begin
        Select @RootHID = Hierarchy From MyTable Where ID = @ParentID
        select @LastHID = Max(Hierarchy) From MyTable where ParentID = @ParentID
    End
    return @RootHID.GetDescendant(@LastHID, NULL)
END

为更新此表也有触发时重新设置层次列ParentID改变。

什么是这个问题的最佳做法是什么?

编辑1:我仰望解决方案,如果可能,不使用触发器。

Answer 1:

我有一个不同的方法来回答这两个问题。 我一般避免使用触发器,直到它是最后的选择,因为它增加了对数据库非必要开销。

触发器和存储过程之比较

  • 这是很容易查看表的关系,约束,索引,存储过程在数据库中,但触发器是难以查看。
  • 触发器执行不可见的客户端应用程序的应用程序。 它们是不可见或可调试的代码进行跟踪。
  • 人们很容易忘记触发器和如果没有文件将很难找出了其存在新的开发。
  • 触发器每次运行时的数据库字段更新,这是头顶上的系统。 它使系统运行变慢。

说够了,这就是为什么我喜欢存储的特效。 您可以创建一个作业文件(说为前:每30分钟,或任何其他的时间后执行),通过代理。 您可以在工作文件中使用逻辑插入。 这样,您的数据tree table将接近实时。

现在参照创建代理:
http://msdn.microsoft.com/en-us/library/ms191128(v=sql.90).aspx
http://msdn.microsoft.com/en-us/library/ms181153(v=sql.105).aspx



Answer 2:

你问的最佳实践。

最好的做法是不要使用邻接表模型(这是你所拥有的),而是切换到嵌套集模型。

它更难以编码和理解,这就是为什么它不是受欢迎,但它更灵活。



Answer 3:

你应该在这方面使用触发器没有游标

ALTER TRIGGER [TR_MyTable_BeforInsert] ON [MyTable]
INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    Insert Into MyTable (Name, ParentID, Hierarchy)
    Select Name, ParentID, dbo.F_MyTableGetHID(NULL, ParentID)
    From inserted
END


Answer 4:

您可以创建计算HIERARCHYID值的函数,考虑到外键父。 然后,你可以调用这个函数作为列的默认值计算器。 如果你阻止用户插入此列,默认值将始终适用。

该解决方案将工作,只有当亲子关系是不可更新的。



Answer 5:

无需光标

只是使用

Insert Into MyTable (Name, ParentID, Hierarchy) 
 select Name, ParentID, dbo.F_MyTableGetHID(NULL, ParentID)   
  from inserted

你能解释的功能 - 不SUR什么它做什么。 但看起来可能变成一个查询,并可以因此用上述组合 - 最佳实践始终不设置理论的关系型数据库



文章来源: Generate Hierarchy value automatically