自动生成层次结构值

meh*_*tfi 8 sql sql-server sql-server-2008 sql-server-2008-r2

我有一个树表列ID,ParentIDHierarchy和要生成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
Run Code Online (Sandbox Code Playgroud)

功能:

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
Run Code Online (Sandbox Code Playgroud)

对于更新,此表还具有触发器以在ParentID更改时再次设置"层次结构"列.

这个问题的最佳实践是什么?

编辑1:我查找解决方案,如果可能的话不使用触发器.

NG.*_*NG. 3

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

触发器和存储过程的比较

  • 查看数据库中的表关系、约束、索引、存储过程很容易,但触发器很难查看。
  • 触发器的执行对客户端应用程序不可见。它们不可见或可以在调试代码中跟踪。
  • 触发器很容易被忘记,如果没有文档,新开发人员将很难弄清楚它们的存在。
  • 每次更新数据库字段时都会运行触发器,这会增加系统开销。它使系统运行速度变慢。

说得够多了,这就是我更喜欢存储过程的原因。您可以通过代理创建一个作业文件(例如:它每 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