【发布时间】:2014-01-16 13:31:55
【问题描述】:
我有一个包含很多表的 Sql-Server 数据库(2008R2,如果这很重要的话)。 有些表包含对其他表的外键引用,有些外键约束在删除时有级联,有些是限制删除。
为了用户友好,在我的应用程序中,我想找出所有其他需要删除的引用,然后才能删除我当前正在删除的引用并将其呈现给用户。 下面描述的一些一般性问题:
我尝试从 Id = 1 且 Order 对 Customer 有一个外键的 Customer 中删除(并且该外键限制用户在删除订单之前删除客户),我希望获得所有 Orders 的结果这限制了我删除客户。
如果合同也有对客户的引用,并且该外键是级联的,但警报引用合同并限制删除,我想知道哪个合同导致无法删除客户,并且导致无法删除客户的警报。
我希望这种行为是递归的,以便我获得所有直接或间接的连接,这些连接首先阻碍了我删除客户。我还希望能够从我开始的任何地方获取此信息(无论我是否想删除客户、订单、警报等)
感觉好像有人在我之前遇到过类似的问题,但我主要可以找到信息来获取 table->table 外键限制,而不是与数据库中的特定实体(即 Id = 1 的客户)相关
有什么简单的方法吗?
【问题讨论】:
-
没有任何我知道的内置内容。在任意大小的数据库中计算所有 FK 引用的传递闭包可能会非常昂贵。这就是为什么服务器在遇到第一个障碍时立即放弃的原因。
-
这正是你应该不做的。您应该从不自动删除行。您应该始终与这些行有一个已知的关系,并就是否应该删除这些行做出明智的决定。你是程序员,而不是用户,当然也不是程序。如果一行应该阻止主行被删除,那么“想办法就去做”就会绕过它。此外,要删除这些其他行,您可能必须删除其他地方的其他行等。我的建议:不要这样做!
-
如果数据库设计正确,你应该可以只获得与要删除的实体的直接关系。也就是说,如果您因为该客户下的订单而无法删除该客户,那么这应该是一个“足够友好”的理由,无需详细说明即可将其退回给客户。
-
@EmmadKareem 这可能没问题,但对我们来说(我们确实拥有的遗留系统),我们有多达 7 个以上依赖深度的表结构。可以肯定的是,用户获得了需要删除其订单的信息,但是当它尝试删除订单时,他获得了需要先删除其他内容的信息,而当尝试删除时,他......获得了更多有关需要删除的内容的信息。
-
不,没有简单的方法。
标签: sql sql-server