【问题标题】:SQL Server: Deleting Rows with Foreign Key Constraints: Can Transactions override the constraints?SQL Server:删除具有外键约束的行:事务可以覆盖约束吗?
【发布时间】:2010-04-29 19:13:26
【问题描述】:

我有几个表添加了外键约束。这些与代码生成一起用于在生成的存储过程中设置特定的连接。

是否可以通过在事务中调用多个删除来覆盖这些约束,特别是 C# 中的“TransactionScope”,还是绝对需要级联删除?

【问题讨论】:

    标签: sql sql-server sql-server-2008 transactions constraints


    【解决方案1】:

    不要使用级联删除,那样会导致严重的性能问题。最好的过程是按从最低的子表到父表的顺序进行删除。

    禁用外键是解决数据完整性问题的方法。唯一应该由经验丰富且非常了解可能导致的问题的 DBA 来执行此类操作。如果您问这个问题,那么您还没有足够的经验来使用该技术。请记住,当您禁用 FK 时,您会为所有人禁用它,而不仅仅是您的进程。

    【讨论】:

    • OP 说:...Foreign Key constraints are added. These are used with code generation to set up specific joins in generated stored procedures.
    • @HLGEM:我同意在这种情况下(在我的一个 cmets 中的另一个答案中进行了描述)按照最低孩子的顺序仔细删除可能是最好的选择。
    • 我不同意级联删除会导致性能问题。事实上,它们是最有效的解决方案(查看执行计划)。如果您手动执行,则必须执行相同数量的工作,但效率较低。
    【解决方案2】:

    “覆盖”foreign key constraint 的唯一方法是禁用它:

    禁用 FOREIGN KEY 约束允许修改表中的数据而无需通过约束验证。如果新数据将违反约束或约束应仅应用于数据库中已有的数据,则在 INSERT 和 UPDATE 语句期间禁用 FOREIGN KEY 约束。

    您需要使用ALTER TABLE 命令禁用约束,使用NOCHECK 关键字。即:

    ALTER TABLE dbo.cnst_example NOCHECK CONSTRAINT salary_cap;
    

    唯一的其他选择是删除约束,并在必要时重新添加。

    这样做的必要性应该会引发关于如何为表格建模的讨论,因此没有必要这样做。

    【讨论】:

    • +1,正是我的想法,如果 FK 仅用于代码生成实用程序来创建一些存储过程,那么删除它们就不是问题了。
    • KM:我们经常做代码生成,通常会删除生产数据库的约束,也很少删除任何记录。所以约束通常不是问题。在新的多租户模型中,我们考虑将它们保留在其中,但删除一个必需的整个租户会给我们带来这个外键问题。我宁愿不禁用/启用或删除/创建约束。我想我们可以 carfeull 构建删除顺序(这似乎是一个显而易见的选择,或者我们不能像你提到的那样使用约束。
    • @Mark Redman:如果没有适当的约束,数据完整性是非常值得怀疑的。
    • 这取决于在维护完整性方面还需要什么,但总的来说是的,我同意。
    【解决方案3】:

    您不能覆盖 FK 约束,如果可以的话,首先创建它们有什么意义?

    【讨论】:

    • 真的,我的意思是,我猜是:在事务结束之前不会在行上验证/检查外键约束/引用,因此不需要完成级联删除。
    • 我不这么认为;即使在事务内部,也会强制执行关系完整性。正如 OMG 指出的那样,您可以禁用 FK。
    • 很遗憾,在事务结束时(或启用/配置这样做)没有检查完整性,这会有所帮助。
    【解决方案4】:

    如果您的 FK 约束是专门为存储过程中的特定用途而设置的,那么这些不是真的 FK,不是吗?一个不错的解决方案是通过在 proc 的开头创建约束来更新相应的代码,并在代码完成时清除它们。然后不要忘记处理无法根据数据检查临时约束的情况。

    【讨论】:

    • 它们用于在代码生成中设置一些连接(选择等),但如果保留 FK,则按设计工作。
    【解决方案5】:

    可以将约束设置为立即或延迟到事务结束。延迟到事务结束允许您在构建事务时违反约束,但在事务结束时强制执行它们。据我了解,延迟到交易结束可能是您所追求的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 2011-12-11
      相关资源
      最近更新 更多