如何使用一个SQL查询从数据库中删除所有表?


176

我不想键入所有表的名称以删除所有表。一个查询可以吗?


3
一些快速谷歌搜索发现这一点:stackoverflow.com/questions/11053116/...
JSK NS

: -尽管(对SQLServer的),这可能是比较有用stackoverflow.com/questions/536350/...

使用正确的用户名,这可能会自动发生(必填xkcd链接)。
Minnow

11
数据库中的表上是否有任何外键?如果是这样,则需要考虑这一点,并在尝试删除表之前先删除它们。
安东尼·格里斯

请记住,如果有架构绑定的对象,则不能删除该表。
肖恩·朗格2014年

Answers:


176

使用INFORMATION_SCHEMA.TABLES视图获取表列表。在select语句中生成Drop脚本,并使用Dynamic SQL将其删除:

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) + '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

系统表版本

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' Drop table ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + '; '
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'

Exec sp_executesql @sql

注意:如果foreign Keys在表之间定义了任何定义,则首先运行以下查询以禁用foreign keys数据库中所有存在的内容。

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

有关更多信息,请在此处检查


3
(不是我的不赞成)... [sys]如果不需要跨rdbms的可移植性,我通常会坚持使用架构视图。stackoverflow.com/a/3654313/251174
swasheck 2014年


1
@DoubleA-非常简单。首先,为数据库中的所有表构建Drop语句,并将其存储到变量中。要检查这一点,您可以使用Print @sql之前exec。然后通过sp_executesql
Pரதீப்2016年

2
如果使用的是Azure,则sp_msforeachtable不可用。我从@Aaron Bertrand找到了这个甜蜜的小块,删除了所有FK约束。这个答案真的很好用。dba.stackexchange.com/questions/90033/…–
trevorc

3
如果sp_msforeachtable不可用,您也可以多次运行delete查询,因​​为依赖于其他表的表随后将被删除:)
Maarten Kieft,

88

如果只想使用一个SQL查询来删除所有表,则可以使用以下命令:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

这是sql server中的隐藏存储过程,将对您连接的数据库中的每个表执行该操作。

注意:由于依赖关系,您可能需要执行几次查询才能删除所有表。

注意2:为避免产生第一条注释,请在运行查询之前首先检查是否有与任何表的外键关系。如果存在,则通过运行以下查询来禁用外键约束:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

1
我在我的Azure SQL数据库上尝试过,但是没有用。但是上述答案(由Prdp提供)有效。
Artemious

4
需要注意的是,在删除所有表之前,我需要多次运行first命令,但工作正常。
Alper

1
@Thatshowweroll可能是由于表的依赖性。如果一个表有其他依赖它的表,则不能删除它。
RageAgainstTheMachine

1
@RageAgainstTheMachine是的,肯定是来自具有多个交叉依赖关系的表。我想通知用户多次运行它,错误不是问题。运行第一个命令3-4次,然后运行第二个命令1次和BOM。它像魅力一样运作!
Alper

1
@KyleVassella是的,这只会在您打开了控制台的数据库上执行
RageAgainstTheMachine

39

如果您不想键入,则可以使用以下命令创建语句:

USE Databasename

SELECT  'DROP TABLE [' + name + '];'
FROM    sys.tables

然后复制并粘贴到新的SSMS窗口中以运行它。


表名应该用[]
换行

1
我们也可以使用QUOTENAME看起来整洁的东西。'DROP TABLE ' + QUOTENAME(name) + ';'
Pரதீப்

13

您还可以使用以下脚本删除所有内容,包括以下内容:

  • 非系统存储过程
  • 意见
  • 功能
  • 外键约束
  • 主键约束
  • 桌子

https://michaelreichenbach.de/how-to-drop-everything-in-a-mssql-database/

/* Drop all non-system stored procs */
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)

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

WHILE @name is not null
BEGIN
    SELECT @SQL = 'DROP PROCEDURE [dbo].[' + RTRIM(@name) +']'
    EXEC (@SQL)
    PRINT 'Dropped Procedure: ' + @name
    SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0 AND [name] > @name ORDER BY [name])
END
GO

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

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

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

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

SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 ORDER BY [name])

WHILE @name IS NOT NULL
BEGIN
    SELECT @SQL = 'DROP FUNCTION [dbo].[' + RTRIM(@name) +']'
    EXEC (@SQL)
    PRINT 'Dropped Function: ' + @name
    SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 AND [name] > @name ORDER BY [name])
END
GO

/* Drop all Foreign 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 = 'FOREIGN 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 = 'FOREIGN 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 FK Constraint: ' + @constraint + ' on ' + @name
        SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN 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 = 'FOREIGN KEY' ORDER BY TABLE_NAME)
END
GO

/* 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

9

我只需要对@NoDisplayName的答案进行一些小的更改,并QUOTENAME()在该TABLE_NAME列上使用它,并包括该TABLE_SCHEMA列以防止表不在dbo模式中。

DECLARE @sql nvarchar(max) = '';

SELECT @sql += 'DROP TABLE ' + QUOTENAME([TABLE_SCHEMA]) + '.' + QUOTENAME([TABLE_NAME]) + ';'
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE [TABLE_TYPE] = 'BASE TABLE';

EXEC SP_EXECUTESQL @sql;

或使用sys架构视图(根据@swasheck的评论):

DECLARE @sql nvarchar(max) = '';

SELECT @sql += 'DROP TABLE ' + QUOTENAME([S].[name]) + '.' + QUOTENAME([T].[name]) + ';'
FROM [sys].[tables] AS [T]
INNER JOIN [sys].[schemas] AS [S] ON ([T].[schema_id] = [S].[schema_id])
WHERE [T].[type] = 'U' AND [T].[is_ms_shipped] = 0;

EXEC SP_EXECUTESQL @sql;

4
[sys]如果不需要跨rdbms的可移植性,我通常会坚持使用架构视图。stackoverflow.com/a/3654313/251174
swasheck 2014年

1
@swasheck感谢您提供非常有趣的链接。我已经使用sys模式视图的解决方案更新了答案。
AeroX 2014年

您可以使用Schema_name()函数来获取架构名称,而不是加入msdn.microsoft.com/en-us/library/ms175068.aspx
2014年

@NoDisplayName仅仅因为您可以,并不意味着您应该 ... blogs.sqlsentry.com/aaronbertrand/…–
Aaron Bertrand

@AaronBertrand-我不好的想法可能是更好的方法。感谢您指出。
2014年

9

作为Dave.Gugg回答的后续,这将是某些人需要获取MySQL中所有DROP TABLE行的代码:

SELECT CONCAT('DROP TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = 'your_database_name'

2
我知道原来的问题用“ sql-server”标记,但对于希望在MySQL中执行此操作的人来说可能很有用。实际上,当我搜寻该问题的MySQL解决方案时就发现了这个问题,因此,在阅读此处的答案之一后,我现在将分享我提出的解决方案。
OMA 2015年

7

最简单的方法是删除整个数据库,然后再次创建它:

drop database db_name
create database db_name

就这样。


1
:)至少对我而言,删除所有表的目的是因为无法删除数据库
Hasan Zafari

5
不要在公司的数据库上运行此命令。或准备寻找另一份工作。
法拉兹

@FarazDurrani容易的人,删除所有表对于PROD db似乎也不是一件好事。
监督

5

如果有人对最佳答案的解决方案有任何疑问(包括禁用外键),这是我的另一种解决方案

-- CLEAN DB
USE [DB_NAME]
    EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
    EXEC sp_MSForEachTable 'DELETE FROM ?'

    DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR
    SET @Cursor = CURSOR FAST_FORWARD FOR

    SELECT DISTINCT sql = 'ALTER TABLE [' + 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

    EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'

3

不完全是1个查询,仍然非常简短和甜美:

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

3

使用下面的脚本dropconstraints

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' ALTER TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) +    ' NOCHECK CONSTRAINT all; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

然后运行以下命令删除所有表:

select @sql='';

SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) + '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

这在'sp_msforeachtable'没有可用的Azure SQL数据库中为我工作!


1

我知道这个问题很老,但是每当我需要此代码时..如果您有表和视图以及函数和过程,则可以通过此脚本将其全部删除..那么为什么我要发布此脚本?因为如果您删除所有表,您将需要删除所有视图,并且如果您具有功能和过程,您也需要删除它,
我希望它将对某人有所帮助

DECLARE @sql NVARCHAR(max)=''

 SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) 
+ '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql


 DECLARE @sql VARCHAR(MAX) = ''
    , @crlf VARCHAR(2) = CHAR(13) + CHAR(10) ;

 SELECT @sql = @sql + 'DROP VIEW ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + 
 QUOTENAME(v.name) +';' + @crlf
 FROM   sys.views v

 PRINT @sql;
 EXEC(@sql);

 declare @procName varchar(500)
 declare cur cursor 

 for select [name] from sys.objects where type = 'p'
 open cur
 fetch next from cur into @procName
 while @@fetch_status = 0
 begin
  exec('drop procedure [' + @procName + ']')
fetch next from cur into @procName
 end
  close cur
  deallocate cur

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

    SELECT @sql = @sql + N' DROP FUNCTION ' 
               + QUOTENAME(SCHEMA_NAME(schema_id)) 
               + N'.' + QUOTENAME(name)
    FROM sys.objects
  WHERE type_desc LIKE '%FUNCTION%';

   Exec sp_executesql @sql
  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.