关于sql:无法删除对象’dbo.Table1’,因为它是由FOREIGN KEY约束引用的

Could not drop object 'dbo.Table1' because it is referenced by a FOREIGN KEY constraint

即使我正在删除并试图删除表,我得到错误,

1
2
3
4
5
ALTER TABLE [dbo].[Table1] DROP CONSTRAINT [FK_Table1_Table2]
GO

DROP TABLE [dbo].[Table1]
GO

错误

Msg 3726, Level 16, State 1, Line 2 Could not drop object 'dbo.Table1'
because it is referenced by a FOREIGN KEY constraint.

使用SQL Server 2012

我使用sql server 2012生成了脚本,所以sQL服务器给了我错误的脚本吗?


不确定我是否正确理解你想要做什么,很可能Table1在另一个表中被引用为FK。

如果你这样做:

1
EXEC sp_fkeys 'Table1'

(这取自如何列出引用SQL Server中给定表的所有外键?)

这将为您提供"Table1"主键为FK的所有表。

删除表中存在的约束,这不是删除表本身的必要步骤。删除引用'Table1'的每个可能的FK是。

至于问题的第二部分,SQL Server自动脚本在很多方面都是盲目的。很可能是阻止您删除Table1的表被删除或者根本没有被脚本更改。 RedGate有一些工具可以帮助那些级联删除(通常在你试图删除一堆表时),但它不是防弹的,而且相当昂贵。 http://www.red-gate.com/products/sql-development/sql-toolbelt/


首先,你需要放弃你的FK。

我建议你看看这个堆栈溢出帖子,非常有趣。它被称为:SQL DROP TABLE外键约束

有关如何执行此过程的良好解释。

我会引用一个回复:

.....Will not drop your table if there are indeed foreign keys referencing it.

To get all foreign key relationships referencing your table, you could use this SQL (if you're on SQL Server 2005 and up):

1
2
3
4
5
6
7
8
9
10
11
SELECT *
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')


SELECT
'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(parent_object_id) +
'.[' + OBJECT_NAME(parent_object_id) +
'] DROP CONSTRAINT ' + name
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')


您可以使用这些查询查找表中的所有FK,并在使用表的表中查找FK。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
DECLARE @SchemaName VARCHAR(200) = 'Your Schema name'
DECLARE @TableName VARCHAR(200) = 'Your Table Name'

-- Find FK in This table.
SELECT
    ' IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id =
OBJECT_ID(N'
'' +
      '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
+ ''') AND parent_object_id = OBJECT_ID(N''' +
      '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' +
OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +

    'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(FK.parent_object_id) +
    '.[' + OBJECT_NAME(FK.parent_object_id) +
    '] DROP CONSTRAINT ' + FK.name
    , S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects AS O
  ON (O.object_id = FK.parent_object_id )
INNER JOIN SYS.schemas AS S
  ON (O.schema_id = S.schema_id)  
WHERE
      O.name = @TableName
      AND S.name = @SchemaName


-- Find the FKs in the tables in which this table is used
  SELECT
    ' IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id =  
      OBJECT_ID(N'
'' +
      '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
  + ''') AND parent_object_id = OBJECT_ID(N''' +
      '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' +
 OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +

    ' ALTER TABLE ' +  OBJECT_SCHEMA_NAME(FK.parent_object_id) +
    '.[' + OBJECT_NAME(FK.parent_object_id) +
    '] DROP CONSTRAINT ' + FK.name
    , S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects AS O
  ON (O.object_id = FK.referenced_object_id )
INNER JOIN SYS.schemas AS S
  ON (O.schema_id = S.schema_id)  
WHERE
      O.name = @TableName
      AND S.name = @SchemaName

您需要将FK放在已添加到的表上,现在这可以是Table2,Table3或任何表,它将Table1的列引用为外键。然后你可以删除Table1。


发生这种情况是因为您尝试更改的表具有主键(PK),该键在不同表中的某处被引用为外键(FK)。要知道它是哪个表,请执行以下存储过程:

EXEC sp_fkeys 'Table_Name'

然后运行drop命令,如下所示:

DROP TABLE Table_Name

注意:'dbo。'是一个默认的系统派生模式,因此你不必在命令中提到如下。即使你提到它将工作的模式也不用担心。

DROP TABLE dbo.Table_Name