【问题标题】:MS SQL Trigger update call dead lock?MS SQL 触发器更新调用死锁?
【发布时间】:2008-11-17 23:57:58
【问题描述】:

我有两张桌子。俱乐部和教练。 它们之间是 0,1 - 0,1 关系(教练可以有零个或一个俱乐部。俱乐部可以有零个或一个教练)。 当我想更换给定俱乐部的教练时,我必须更新俱乐部表。所以我必须改变那个俱乐部的idCoach。让我们考虑一位新教练(给定俱乐部的新指定教练)已经是其他俱乐部的教练。我必须将那个俱乐部的 idCoach 字段设置为 Null,因为他的教练将被分配到另一个俱乐部。 此外,如果我想更换教练的俱乐部已经有教练,那么我必须将该教练的 idClub (在教练表中)设置为 Null。

以上所有内容,也适用于我想更换某个教练的俱乐部时。 (必须将给定教练的前一家具乐部的 idCoach 字段设置为空,并且必须将新俱乐部的 idCoach 设置为空)。

当我在 Club 或 Coach 表中插入新记录或删除现有记录时,可能会出现同样的问题(在插入、更新和删除时,我必须注意相应的引用并取消它们的链接)。

我想用触发器解决这个问题。我想我必须在 Club 表中有 3 个触发器(用于插入、更新和删除),在 Coach 表中还有 3 个。

在更新触发器中(例如在俱乐部中)我必须更新教练表,这将再次触发俱乐部中的更新(因为在它的主体中它必须更新俱乐部表)并且该触发器将更新教练和触发器等等。所以我会有一个死锁。

如何解决?

这是我第一次使用触发器,非常抱歉,对于一个简单的事情的大解释。

干杯!

【问题讨论】:

    标签: sql sql-server triggers


    【解决方案1】:

    我认为这可能不适合用于触发器,因为触发器非常难以调试,并且经常以他们不支持单记录操作的方式让人们感到惊讶,正如您所期望的那样。将其分解为简单的 SQL 语句,然后围绕它包装一个事务。

    【讨论】:

    • 这就是为什么不允许新开发者创建触发器的原因。我觉得奇怪的是人们会认为它一次只能处理一条记录,但我是一名数据库专家,我认为是成套的。我从来没有想过他们不会成套工作。
    • 我有一个触发器调试过程,如果您有兴趣,它会相对容易。评论太长了,但如果你想看的话,我可以添加到这个问题的结尾。
    【解决方案2】:

    可以有第三张桌子,它可以保存关系吗?我认为这将是一种简单的工作方法。

    如果教练从俱乐部辞职,只需从新表中删除记录。 为加入新俱乐部的教练插入记录。

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      如果可以,我建议避免使用触发器。如果您必须尝试使用​​代替触发器而不是普通触发器。不同之处在于在实际修改任何数据之前触发触发器。话虽如此,我认为你最好使用存储过程,看看你是否

      另一个建议是您是否可以将其建模为关联实体。我假设俱乐部的教练也必须是俱乐部的教练。所以你可以做的是创建一个CoachAssignment 表,现在你只需要维护这一条记录。如果您需要一名教练来隶属于多个俱乐部,那么该模型就适合您。

      话虽如此,您可以使用 If Update(FieldName) 语法仅更新您实际需要的表。如果您需要停止递归触发器,您可以通过检查 TRIGGER_NESTLEVEL() 来防止这种情况

      【讨论】:

        【解决方案4】:

        我同意 shahkalpesh - 您的设计应该包括一个 Coach 表、一个 Club 表、第三个表(ClubCoach?)来存储关系。那么你所要做的就是强制执行一个教练不能在外部分配到多个俱乐部(反之亦然)的规则。

        或者,您可以只拥有 Coach 和 Club 表,在 Coach 表中使用 idClub(执行一个教练一个俱乐部的规则),并在外部执行一个教练一个俱乐部的规则。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-23
          • 1970-01-01
          • 2020-01-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多