如何删除SQL Server数据库中的所有表?


195

我正在尝试编写一个脚本,该脚本将完全清空SQL Server数据库。这是我到目前为止的内容:

USE [dbname]
GO
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DELETE ?'

在Management Studio中运行它时,我得到:

命令已成功完成。

但是当我刷新表格列表时,它们仍然存在。我究竟做错了什么?


如果此页面上的所有解决方案均无效,则您可能忘记了:USE [DatabaseName] GO
Serj Sagan 2014年

2
删除?将从表中删除记录。您应该使用DROP TABLE?,但是由于其他原因,它将无法使用。
datagod

Answers:


304

当有多个外键表时,它对我也不起作用。
我发现该代码可以正常工作,并且可以完成您尝试的所有操作(从数据库中删除所有表):

DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR

SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.TABLE_SCHEMA + '].[' +  tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + '];'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME =rc1.CONSTRAINT_NAME

OPEN @Cursor FETCH NEXT FROM @Cursor INTO @Sql

WHILE (@@FETCH_STATUS = 0)
BEGIN
Exec sp_executesql @Sql
FETCH NEXT FROM @Cursor INTO @Sql
END

CLOSE @Cursor DEALLOCATE @Cursor
GO

EXEC sp_MSforeachtable 'DROP TABLE ?'
GO

你可以在这里找到帖子。这是Groker的帖子。


为什么当您尝试使用BEGIN-END块将整个代码块包装在IF语句中时,为什么它抱怨游标?
亚当

11
我遇到了错误Could not find stored procedure 'sp_MSForEachTable'.
Korayem '16

2
如果您的表(带有约束)的模式不同于,则此答案不起作用dbo。如果有自定义模式,您需要更改sql到:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
阿斯比约恩Ulsberg

5
sp_MSforeachtable在Azure中不可用。请使用@CountZero的答案。
Ogglas

3
在网上(不是我的)找到此参考:sp_MSforeachtable Azure的存储过程的副本,使用sp_MSforeach_worker:gist.github.com/metaskills/893599
若昂·维埃拉(JoãoVieira)

328

您也可以仅使用MSSMS UI工具(不使用SQL脚本)从数据库中删除所有表。有时,这种方式可能会更舒适(尤其是偶尔执行)

我按如下步骤进行操作:

  1. 在数据库树上选择“表”(对象资源管理器)
  2. 按F7键打开“对象资源管理器详细信息”视图
  3. 在此视图中,选择必须删除的表(在这种情况下,所有表)
  4. 继续按Delete键,直到所有表都被删除(由于关键的约束/依赖关系,您重复它的次数达到错误数量)

5
我无法使sp_msforeachtable在Azure sql数据库上工作。我猜他们不包括Azure。当通过EF迁移模拟或进行大量更改(重新开始)时,此解决方案效果很好,非常完美。
trevorc

不考虑FK /订单。
乔什

1
如果您只需要在这里和那里做,这是一种方便的方法,如果您经常这样做,脚本可能会更好。
Dylan Hayes

2
@Josh不会考虑顺序,但是如果您在Delete对话框中持续按OK,它将继续删除所有可以的表,最终将删除所有表。
clayRay

使用Designer的完美解决方案
Zaheer

47

在SSMS中:

  • 右键单击数据库
  • 转到“任务”
  • 点击“生成脚本”
  • 在“选择对象”部分中,选择“脚本编写整个数据库和所有数据库对象”
  • 在“设置脚本选项”部分中,单击“高级”按钮
  • 在“ Script DROP and CREATE”上,将“ Script CREATE”切换为“ Script DROP”,然后按OK。
  • 然后,保存到文件,剪贴板或新的查询窗口。
  • 运行脚本。

现在,这将删除所有内容,包括数据库。确保删除不想删除的项目的代码。或者,在“选择对象”部分中,而不是选择对整个数据库编写脚本,只需选择要删除的项目即可。


3
如果您不想删除数据库(在我的情况下不是这样,那么我需要拨打支持电话以创建数据库),然后使用“选择特定的数据库对象”并选择所有你确实希望放弃。
d219

3
这是最简单的方法。
Asiri Dissanayaka,

2
这应该是肯定的答案!
扎克·泰勒

34

delete用于从表中删除行。您应该drop table改用。

EXEC sp_msforeachtable 'drop table [?]'

这似乎已经解决了没有任何错误的问题,但是现在我遇到了约束错误。我的NOCHECK CONSTRAINT行的语法错误吗?
dixuji 2011年

1
我在FK的快速2张桌子上使用了它,并且效果很好。EXEC sp_msforeachtable'ALTER TABLE吗?NOCHECK约束中的所有”
DaveShaw

12
这仅在我删除方括号后才有效:EXEC sp_msforeachtable'drop table?'。
LPains 2015年

在SQL Server上,如果任何表名具有任何奇数字符或空格,则需要使用方括号。我不知道一个不支持对象名称括号的SQL Server版本。
DaveShaw 2015年

在SQL Server 2012(11.x)上,我还必须删除方括号。
Frieder

30

接受的答案不支持Azure。它使用未记录的存储过程“ sp_MSforeachtable”。如果在运行时遇到“无法找到存储过程'sp_msforeachtable”的错误,或者只是想避免依赖未记录的功能(可以随时删除或更改其功能),请尝试以下操作。

此版本忽略实体框架迁移历史记录表“ __MigrationHistory”和“ database_firewall_rules”(这是您无权删除的Azure表)。

在Azure上进行了轻松的测试。请进行检查,以确保这不会对您的环境造成不良影响。

DECLARE @sql NVARCHAR(2000)

WHILE(EXISTS(SELECT 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY'))
BEGIN
    SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
    EXEC(@sql)
    PRINT @sql
END

WHILE(EXISTS(SELECT * from INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'))
BEGIN
    SELECT TOP 1 @sql=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']')
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'
    EXEC(@sql)
    PRINT @sql
END

取自:

https://edspencer.me.uk/2013/02/25/drop-all-tables-in-a-sql-server-database-azure-friendly/

http://www.sqlservercentral.com/blogs/sqlservertips/2011/10/11/remove-all-foreign-keys/


3
曾在天青魔法般的作用。然后快得多了,然后通过VS的用户界面将其删除
Simeon Grigorovich

27
/* Drop all Primary Key constraints */
DECLARE @name VARCHAR(128)
DECLARE @constraint VARCHAR(254)
DECLARE @SQL VARCHAR(254)

SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)

WHILE @name IS NOT NULL
BEGIN
    SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
    WHILE @constraint is not null
    BEGIN
        SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT [' + RTRIM(@constraint)+']'
        EXEC (@SQL)
        PRINT 'Dropped PK Constraint: ' + @constraint + ' on ' + @name
        SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
    END
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)
END
GO

/* Drop all tables */
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)

SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name])

WHILE @name IS NOT NULL
BEGIN
    SELECT @SQL = 'DROP TABLE [dbo].[' + RTRIM(@name) +']'
    EXEC (@SQL)
    PRINT 'Dropped Table: ' + @name
    SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name])
END
GO

1
在SQL Azure中可用:) sp_MSforeachtable在那里不起作用
Pavel Biryukov

请注意,如果您使用的是非dbo模式(例如,如果您使用的是Hangfire),则此操作将失败
Liam Dawson

21

您几乎是正确的,请改用:

EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DROP TABLE ?'

但是第二行,您可能需要执行更多然后执行一次,直到停止出现错误为止:

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

信息:

Command(s) completed successfully.

表示已成功删除所有表。


17

简短而甜美:

USE YOUR_DATABASE_NAME
-- Disable all referential integrity constraints
EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO

-- Drop all PKs and FKs
declare @sql nvarchar(max)
SELECT @sql = STUFF((SELECT '; ' + 'ALTER TABLE ' + Table_Name  +'  drop constraint ' + Constraint_Name  from Information_Schema.CONSTRAINT_TABLE_USAGE ORDER BY Constraint_Name FOR XML PATH('')),1,1,'')
EXECUTE (@sql)
GO

-- Drop all tables
EXEC sp_MSforeachtable 'DROP TABLE ?'
GO

2
我必须替换sp_msforeachtablesp_MSforeachtable,强烈建议添加use yourdatabase第一行。像魅力一样工作。
西蒙·索比斯

简短而甜蜜!谢谢
sapatelbaps,

7

禁食的方式是:

  1. 新数据库图
  2. 添加所有表格
  3. Ctrl + A全选
  4. 右键单击“从数据库中删除”
  5. Ctrl + S保存
  6. 请享用

到目前为止,这是最快,更不容易出错的方法。这应该是公认的答案。
DARKGuy

6

似乎命令应该没有方毯

EXEC sp_msforeachtable 'drop table ?'

6

对我来说,最简单的方法是:

--First delete all constraints

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

SELECT @sql = @sql + N'
ALTER TABLE ' + QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + N' DROP CONSTRAINT '
+ QUOTENAME(c.name) + ';'
FROM sys.objects AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
INNER JOIN sys.schemas AS s 
ON t.[schema_id] = s.[schema_id]
WHERE c.[type] IN ('D','C','F','PK','UQ')
ORDER BY c.[type];

EXEC sys.sp_executesql @sql;

-- Then drop all tables

exec sp_MSforeachtable 'DROP TABLE ?'


1

如何删除整个数据库然后再次创建它?这对我有用。

DROP DATABASE mydb;
CREATE DATABASE mydb;

您是否不需要在两者之间清理mdf和ldf文件?
鲁芬2015年

我正在使用网络托管服务提供商,对此我不太确定。我认为当您删除数据库时,这些文件将自动删除,除非您处于脱机状态。
Chong Lip Phang 2015年

2
这确实取决于情况。就我而言,我没有存储过程,这种方法对我来说很好用。当两行可用时,我不会编写跨越数十行的复杂代码。我认为我的答案不足以支持我,因为我向特定的用户群提供了建议。
Chong Lip Phang 2015年

0

我知道这是一篇老文章,但是我已经在许多数据库上尝试过这里所有的答案,但我发现它们有时都可以工作,但对于SQL Server的各种(我只能假设)怪癖来说,并非总是如此。

最终我想到了这个。我已经在所有地方(通常来说)进行了测试,并且可以正常工作(没有任何隐藏的存储过程)。

需要注意的主要是有关SQL Server 2014的信息。(但是我尝试过的大多数其他版本似乎也能正常工作)。

我尝试了while循环和null等,游标和各种其他形式,但是它们似乎总是在某些数据库上失败,而在其他数据库上却没有明显的原因而失败。

在我测试过的所有内容上,获取计数并使用它进行迭代似乎总是可行的。

USE [****YOUR_DATABASE****]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- Drop all referential integrity constraints --
-- Drop all Primary Key constraints.          --

DECLARE @sql  NVARCHAR(296)
DECLARE @table_name VARCHAR(128)

DECLARE @constraint_name VARCHAR(128)
SET @constraint_name = ''

DECLARE @row_number INT

SELECT @row_number = Count(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME

WHILE @row_number > 0
BEGIN
    BEGIN
        SELECT TOP 1 @table_name = tc2.TABLE_NAME, @constraint_name = rc1.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
        LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME
        AND rc1.CONSTRAINT_NAME > @constraint_name
        ORDER BY rc1.CONSTRAINT_NAME
        SELECT @sql = 'ALTER TABLE [dbo].[' + RTRIM(@table_name) +'] DROP CONSTRAINT [' + RTRIM(@constraint_name)+']'
        EXEC (@sql)
        PRINT 'Dropped Constraint: ' + @constraint_name + ' on ' + @table_name
        SET @row_number = @row_number - 1
    END
END
GO

-- Drop all tables --

DECLARE @sql  NVARCHAR(156)
DECLARE @name VARCHAR(128)
SET @name = ''

DECLARE @row_number INT

SELECT @row_number = Count(*) FROM sysobjects WHERE [type] = 'U' AND category = 0

WHILE @row_number > 0
BEGIN
    SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name])
    SELECT @sql = 'DROP TABLE [dbo].[' + RTRIM(@name) +']'
    EXEC (@sql)
    PRINT 'Dropped Table: ' + @name
    SET @row_number = @row_number - 1
END
GO

0

对于Temporal Tables,由于可能存在一些外键和例外,所以它稍微复杂一些:

Drop table operation failed on table XXX because it is not a supported operation on system-versioned temporal tables

您可以使用的是:

-- Disable constraints (foreign keys)
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO

-- Disable system versioning (temporial tables)
EXEC sp_MSForEachTable '
 IF OBJECTPROPERTY(object_id(''?''), ''TableTemporalType'') = 2
  ALTER TABLE ? SET (SYSTEM_VERSIONING = OFF)
'
GO

-- Removing tables
EXEC sp_MSForEachTable 'DROP TABLE ?'
GO
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.