使用sp_msforeachtable禁用FK约束会产生FK错误

时间:2012-11-20 11:53:56

标签: sql-server-2008

我刚刚为遗留数据库添加了大约80个“丢失”外键,并且(不出所料)数据库重新创建脚本现在因FK约束而丢弃表时失败。策略一直是按自然顺序删除表,这一直到现在为止。我不想保持这种方法,并尝试禁用所有FK约束,如下所示:

USE MYDB;
GO

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
GO

DROP TABLE [dbo].[Table1]
DROP TABLE [dbo].[Table2]
DROP TABLE [dbo].[Table3]
...

exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
GO

问题是我仍然遇到错误:

  

Msg 3726,Level 16,State 1,Line 17无法掉落物体   'dbo.Table1'因为它是由FOREIGN KEY约束引用的。消息   3726,Level 16,State 1,Line 18无法删除对象'dbo.Table2'   因为它是由FOREIGN KEY约束引用的。

任何人都可以建议我做错了吗?我在Windows 7上使用SQL Server 2008 r2。

编辑:我注意到我有一个循环引用,即Table1有一个FK到Table2,反之亦然,但即便如此....

1 个答案:

答案 0 :(得分:1)

您可以在运行drop table命令之前删除所有约束。在脚本顶部的这样的东西应该可以工作。

   declare @newLine as varchar(1) = char(13);
   declare @sqlCmd as varchar(max) = '';

   SELECT @sqlCmd = @sqlCmd + 'alter table ' + OBJECT_NAME(parent_object_id) + ' drop constraint ' + OBJECT_NAME(OBJECT_ID) + ';' + @newLine
   FROM sys.objects
   WHERE type_desc LIKE '%CONSTRAINT'
         and OBJECT_NAME(parent_object_id) not in ('list','of','tables','to','ignore')
  order by case when left(OBJECT_NAME(OBJECT_ID),2) = 'PK' then 1 else 0 end
  exec (@sqlCmd)
  go