【问题标题】:How to drop all FK contraints referencing a table and add them back? [duplicate]如何删除所有引用表的 FK 约束并将它们添加回来? [复制]
【发布时间】:2021-08-14 18:57:10
【问题描述】:

我在 SSMS 2016 中使用此命令

EXEC sp_fkeys mytable1

并且我有超过 30 个 FK 约束引用此表中的列。如何一次性删除所有约束,进行一些截断工作(需要将表从一台服务器复制到另一台服务器)并将它们全部添加回来?

【问题讨论】:

  • 您可以禁用约束,但我认为这不会让您截断。禁用它们后删除速度更快。
  • @paparazzo 删除速度怎么样? Paul White 有一篇很棒的帖子,但也许你是从我不知道的角度来看这个的。
  • @scsimon 它更快,因为它不必测试参照完整性。

标签: sql-server foreign-keys truncate


【解决方案1】:

我找到了答案,我需要先禁用所有外键约束,然后像狗仔队所说的那样删除数据,然后重新启用它们。

以下是脚本:

禁用外键约束。

DECLARE @sql NVARCHAR(MAX) = N'';   

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' NOCHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

重新启用它们

DECLARE @sql NVARCHAR(MAX) = N'';

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' WITH CHECK CHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

【讨论】:

    【解决方案2】:

    查看我的第一条评论。删除而不是截断。禁用约束,以便删除更快,因为它们不检查参照完整性。您需要在子级和父级上禁用。

    ALTER TABLE parent NOCHECK CONSTRAINT ALL;
    ALTER TABLE child NOCHECK CONSTRAINT ALL;
    delete parent where pk = 1
    ALTER TABLE parent CHECK CONSTRAINT ALL
    ALTER TABLE child CHECK CONSTRAINT ALL;
    

    【讨论】:

      【解决方案3】:

      与其删除约束并重新添加它们(这是很多不必要的工作),不如简单地禁用和启用它们。

      将您的代码放在这两行之间:

      ALTER TABLE mytable1 NOCHECK CONSTRAINT ALL
      
      -- put your code here. Example: DELETE FROM mytable1
      
      ALTER TABLE mytable1 CHECK CONSTRAINT ALL
      

      根据您的表关系,您可能需要禁用引用您的表的其他表的约束。例如,如果您需要禁用两个表的约束:

      ALTER TABLE mytable1 NOCHECK CONSTRAINT ALL
      ALTER TABLE mytable2 NOCHECK CONSTRAINT ALL
      
      -- put your code here. Example: DELETE FROM mytable1
      
      ALTER TABLE mytable2 CHECK CONSTRAINT ALL
      ALTER TABLE mytable1 CHECK CONSTRAINT ALL
      

      如果您想禁用和启用数据库中的所有约束(除非您知道自己在做什么,否则不推荐),您可以使用:

      EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
      
      -- put your code here. Example: DELETE FROM mytable1
      
      EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
      

      【讨论】:

      • 问题是我不能用这个截断。我不断收到消息“无法截断表 'mytable1',因为它被 FOREIGN KEY 约束引用”
      • 是的,就像cmets中提到的狗仔队一样,使用DELETE而不是TRUNC
      • 查看我的评论。我不认为这会让你截断。
      • 如果我删除它们,我该如何添加它们?这些约束有 30 多个引用表
      • 是的,不幸的是我也试过了。我收到 DELETE 语句与 REFERENCE 约束“FK_constraintName”冲突。遍历每个表来删除 FK 约束太乏味了,这就是我问原始问题的原因
      猜你喜欢
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多