SQL DROP TABLE外键约束

时间:2009-11-21 17:15:07

标签: sql-server foreign-keys constraints database-table drop-table

如果我想像这样删除数据库中的所有表,它会处理外键约束吗?如果没有,我该如何处理?

GO
IF OBJECT_ID('dbo.[Course]','U') IS NOT NULL
    DROP TABLE dbo.[Course]
GO
IF OBJECT_ID('dbo.[Student]','U') IS NOT NULL
    DROP TABLE dbo.[Student]

14 个答案:

答案 0 :(得分:298)

不,如果确实有外键引用它,这不会丢弃你的表。

要获取引用表的所有外键关系,可以使用此SQL(如果您使用的是SQL Server 2005及更高版本):

SELECT * 
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

如果有的话,在这里使用此语句,您可以创建SQL语句来实际删除这些FK关系:

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')

答案 1 :(得分:33)

在SQL Server Management Studio 2008(R2)及更高版本中,您可以右键单击

  

DB - >任务 - >生成脚本

  • 选择要删除的表格。

  • 选择“保存到新查询窗口”。

  • 单击“高级”按钮。

  • 将脚本DROP和CREATE设置为Script DROP。

  • 将脚本外键设置为True。

  • 单击“确定”。

  • 点击下一步 - >下一步 - >完成。

  • 查看脚本,然后执行。

答案 2 :(得分:18)

如果先删除“子”表,外键也将被删除。如果您首先尝试删除“父”表,您将得到“无法删除对象'a',因为它是由FOREIGN KEY约束引用的。”错误。

答案 3 :(得分:13)

以下是使用sp_MSdropconstraints过程正确删除所有表的另一种方法。我能想到的最短的代码:

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";

答案 4 :(得分:2)

如果是SQL Server,则必须先删除约束,然后才能删除该表。

答案 5 :(得分:2)

@mark_s发布的更为通用的版本,这对我有帮助

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

只需插入您的表名,然后执行结果。

答案 6 :(得分:1)

这是另一种方法,使用涉及FOR XML PATH('')的串联技巧删除表本身后面的所有约束,允许将多个输入行合并为单个输出行。应该适用于任何SQL 2005&后面。

为了安全起见,我已将EXECUTE命令注释掉了。

DECLARE @SQL NVARCHAR(max)
;WITH fkeys AS (
    SELECT quotename(s.name) + '.' + quotename(o.name) tablename, quotename(fk.name) constraintname 
    FROM sys.foreign_keys fk
    JOIN sys.objects o ON fk.parent_object_id = o.object_id
    JOIN sys.schemas s ON o.schema_id = s.schema_id
)
SELECT @SQL = STUFF((SELECT '; ALTER TABLE ' + tablename + ' DROP CONSTRAINT ' + constraintname
FROM fkeys
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

SELECT @SQL = STUFF((SELECT '; DROP TABLE ' + quotename(TABLE_SCHEMA) + '.' + quotename(TABLE_NAME) 
FROM INFORMATION_SCHEMA.TABLES 
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

答案 7 :(得分:1)

这是一个实现解决方案的完整脚本:

create Procedure [dev].DeleteTablesFromSchema
(
    @schemaName varchar(500)
)
As 
begin
    declare @constraintSchemaName nvarchar(128), @constraintTableName nvarchar(128),  @constraintName nvarchar(128)
    declare @sql nvarchar(max)
    -- delete FK first
    declare cur1 cursor for
    select distinct 
    CASE WHEN t2.[object_id] is NOT NULL  THEN  s2.name ELSE s.name END as SchemaName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  t2.name ELSE t.name END as TableName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  OBJECT_NAME(d2.constraint_object_id) ELSE OBJECT_NAME(d.constraint_object_id) END as ConstraintName
    from sys.objects t 
        inner join sys.schemas s 
            on t.[schema_id] = s.[schema_id]
        left join sys.foreign_key_columns d 
            on  d.parent_object_id = t.[object_id]
        left join sys.foreign_key_columns d2 
            on  d2.referenced_object_id = t.[object_id]
        inner join sys.objects t2 
            on  d2.parent_object_id = t2.[object_id]
        inner join sys.schemas s2 
            on  t2.[schema_id] = s2.[schema_id]
    WHERE t.[type]='U' 
        AND t2.[type]='U'
        AND t.is_ms_shipped = 0 
        AND t2.is_ms_shipped = 0 
        AND s.Name=@schemaName
    open cur1
    fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    while @@fetch_status = 0
    BEGIN
        set @sql ='ALTER TABLE ' + @constraintSchemaName + '.' + @constraintTableName+' DROP CONSTRAINT '+@constraintName+';'
        exec(@sql)
        fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    END
    close cur1
    deallocate cur1

    DECLARE @tableName nvarchar(128)
    declare cur2 cursor for
    select s.Name, p.Name
    from sys.objects p
        INNER JOIN sys.schemas s ON p.[schema_id] = s.[schema_id]
    WHERE p.[type]='U' and is_ms_shipped = 0 
    AND s.Name=@schemaName
    ORDER BY s.Name, p.Name
    open cur2

    fetch next from cur2 into @schemaName,@tableName
    while @@fetch_status = 0
    begin
        set @sql ='DROP TABLE ' + @schemaName + '.' + @tableName
        exec(@sql)
        fetch next from cur2 into @schemaName,@tableName
    end

    close cur2
    deallocate cur2

end
go

答案 8 :(得分:0)

  

如果我要删除所有表格   我的数据库

然后删除整个数据库要容易得多:

DROP DATABASE WorkerPensions

答案 9 :(得分:0)

Removing Referenced FOREIGN KEY Constraints
Assuming there is a parent and child table Relationship in SQL Server:

--First find the name of the Foreign Key Constraint:
  SELECT * 
  FROM sys.foreign_keys
  WHERE referenced_object_id = object_id('States')

--Then Find foreign keys referencing to dbo.Parent(States) table:
   SELECT name AS 'Foreign Key Constraint Name', 
           OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id) AS 'Child Table'
   FROM sys.foreign_keys 
   WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
              OBJECT_NAME(referenced_object_id) = 'dbo.State'

 -- Drop the foreign key constraint by its name 
   ALTER TABLE dbo.cities DROP CONSTRAINT FK__cities__state__6442E2C9;

 -- You can also use the following T-SQL script to automatically find 
 --and drop all foreign key constraints referencing to the specified parent 
 -- table:

 BEGIN

DECLARE @stmt VARCHAR(300);

-- Cursor to generate ALTER TABLE DROP CONSTRAINT statements  
 DECLARE cur CURSOR FOR
 SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.' + 
 OBJECT_NAME(parent_object_id) +
                ' DROP CONSTRAINT ' + name
 FROM sys.foreign_keys 
 WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
            OBJECT_NAME(referenced_object_id) = 'states';

 OPEN cur;
 FETCH cur INTO @stmt;

 -- Drop each found foreign key constraint 
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC (@stmt);
    FETCH cur INTO @stmt;
  END

  CLOSE cur;
  DEALLOCATE cur;

  END
  GO

--Now you can drop the parent table:

 DROP TABLE states;
--# Command(s) completed successfully.

答案 10 :(得分:0)

使用SQL Server Manager,可以从UI删除外键约束。如果要删除表Diary,但是User表具有指向DiaryId表的外键Diary,则可以展开(使用加号)User表,然后展开Foreign Keys部分。右键单击指向日记表的外键,然后选择Delete。然后,您可以展开Columns部分,右键单击并删除列DiaryId。然后,您可以运行:

drop table Diary

我知道您的实际问题是关于删除所有表,因此对于这种情况可能没有用。但是,我相信,如果您只想删除一些表,这很有用(标题没有明确提及删除所有表)。

答案 11 :(得分:0)

执行以下代码,以获取阻止放置的外键约束名称。例如,我使用roles表。

      SELECT *
      FROM sys.foreign_keys
      WHERE referenced_object_id = object_id('roles');

      SELECT name AS 'Foreign Key Constraint Name',
      OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id)
      AS 'Child Table' FROM sys.foreign_keys
      WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo'
      AND OBJECT_NAME(referenced_object_id) = 'dbo.roles'

您将获得FK名称,如下所示:FK__Table1__roleId__1X1H55C1

现在运行下面的代码以删除从上面获得的FK参考。

ALTER TABLE dbo.users drop CONSTRAINT FK__Table1__roleId__1X1H55C1;

完成!

答案 12 :(得分:-1)

如果你在mysql服务器上,如果你不介意丢失你的表,你可以使用一个简单的查询一次删除多个表:

SELECT
    m.store1, m.miles, mitable.region, mitable.terminal, mitable.city, mitable.state
FROM 
    (SELECT 
         store1, MIN (miles) as miles
     FROM
         mitable
     GROUP BY
         region, store1) m
INNER JOIN  
    mitable ON m.store1 = mitable.store1
            AND m.miles = mitable.miles

通过这种方式,您在查询中使用该表的顺序并不重要。

如果你有一个包含许多表的数据库,那么如果有人想说这不是一个好的解决方案这一事实:我同意!

答案 13 :(得分:-3)

如果你想DROP使用外键使用其他表引用的表

DROP TABLE *table_name* CASCADE CONSTRAINTS;
我认为它应该适合你。