我有一个ID和ParentAccountID的帐户表。这是重现步骤的脚本。

如果ParentAccountID为NULL,则将其视为顶级帐户。
每个帐户最终都应以顶级帐户结尾,即ParentAccountID为NULL

    Declare @Accounts table (ID INT, ParentAccountID INT )


    INSERT INTO @Accounts values (1,NULL), (2,1), (3,2) ,(4,3), (5,4), (6,5)

    select * from @Accounts

     -- Request to update ParentAccountID to 6 for the ID 3
    update @Accounts
    set ParentAccountID = 6
    where ID = 3

    -- Now the above update will cause circular reference
    select * from @Accounts

当请求到来要更新一个帐户的ParentAccountID时,如果这引起循环引用,则在更新之前需要先确定它。

任何有想法的人!

最佳答案

看来您已经为表定义了一些业务规则:

  • 所有链必须以顶级帐户
  • 结尾
  • 链可能没有循环引用

  • 您有两种方法可以强制执行此操作。

    您可以在数据库中创建trigger,然后检查触发器中的逻辑。这具有在数据库内部运行的优势,因此它适用于每个事务,而与客户端无关。但是,数据库触发器并不总是很流行。我将它们视为side effect,它们可能很难调试。触发器作为SQL的一部分运行,因此,如果触发器运行缓慢,则SQL将会运行缓慢。

    另一种方法是在应用程序层中强制执行此逻辑-无论与数据库进行通信。这更容易调试,并使您的业务逻辑对新开发人员明确-但它不在数据库中运行,因此如果您有多个客户端应用程序,最终可能会复制逻辑。

    10-06 15:15