【问题标题】:How to drop all tables from a database with one SQL query?如何使用一个 SQL 查询从数据库中删除所有表?
【发布时间】:2015-02-20 18:40:50
【问题描述】:

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

【问题讨论】:

标签: sql sql-server


【解决方案1】:

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

Sys.Tables版本

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"

欲了解更多信息,check here

【讨论】:

  • (不是我的反对意见)...如果不需要跨 rdbms 的可移植性,我通常会坚持使用 [sys] 模式视图。 stackoverflow.com/a/3654313/251174
  • @DoubleA - 这很简单。首先是为我的数据库中的所有表构建 Drop 语句并将其存储到一个变量中。要检查这一点,您可以在exec 之前使用Print @sql。然后通过sp_executesql 执行动态构建的 drop 语句
  • 如果您使用的是 Azure,则 sp_msforeachtable 不可用。我从@Aaron Bertrand 找到了这个甜蜜的金块来删除所有 FK 约束。这个答案真的很好用。 dba.stackexchange.com/questions/90033/…
  • 如果 sp_msforeachtable 不可用,您也可以多次运行 delete 查询,因为依赖于其他表的表随后会被删除:)
【解决方案2】:

如果你只想使用一个 SQL 查询来删除所有表,你可以使用这个:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

这是一个隐藏在 sql server 中的存储过程,将针对你连接的数据库中的每个表执行。

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

注意2:为避免出现第一个注释,在运行查询之前,首先检查是否存在与任何表的外键关系。如果只有disable 外键约束,请运行以下查询:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

【讨论】:

  • 我在我的 Azure SQL 数据库上尝试过,但没有成功。然而,上述答案(由 Prdp 提供)奏效了。
  • 附带说明,我需要在删除所有表之前多次运行第一个命令,但它工作正常。
  • @Thatshowweroll 这可能是因为表的依赖关系。如果一个表有其他依赖于它的表,则无法删除。
  • @RageAgainstTheMachine 是的,它肯定来自具有多个交叉依赖关系的表。我想通知用户多次运行它,错误不是问题。运行第一个命令 3-4 次,然后运行第二个命令 1 次和 BOM。它就像魅力一样!
  • @KyleVassella 是的,这只会在您打开控制台的数据库上执行
【解决方案3】:

如果你不想输入,你可以用这个来创建语句:

USE Databasename

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

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

【讨论】:

  • 表名应该包含在 [ ] 中,但即使在 Azure 上也能很好地工作
  • 我们也可以使用QUOTENAME,看起来很整洁。 'DROP TABLE ' + QUOTENAME(name) + ';'
  • 我们也可以使用这个顺序来避免删除时出现约束问题。按 create_date desc 排序
【解决方案4】:

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

  • 非系统存储过程
  • 观看次数
  • 功能
  • 外键约束
  • 主键约束
  • system_versioning
  • 表格

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

/* Remove system versioning */
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
    IF OBJECTPROPERTY(OBJECT_ID(' + @name + '), 'TableTemporalType') = 2 
        SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] SET (SYSTEM_VERSIONING = OFF); ALTER TABLE [dbo].[' + RTRIM(@name) + '] DROP PERIOD FOR SYSTEM_TIME;'
        EXEC (@SQL)
        PRINT 'System Versioning Disabled for Table: ' + @name
        SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [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

【讨论】:

  • 抱歉,此脚本不适用于多模式。您已硬编码“[dbo]”。在脚本的多行中。
  • 运行良好.. 删除表格的最佳脚本。
【解决方案5】:

最简单的方法是删除整个数据库并重新创建:

drop database db_name
create database db_name

就是这样。

【讨论】:

  • :) 至少对我来说删除所有表的目的是因为无法删除数据库
  • 不要在公司的数据库上运行这个命令。或者准备好找另一份工作。
  • @FarazDurrani 简单的人,删除所有表对于 PROD db 似乎也不是一笔交易。
  • 小心。这将清除与表关联的所有其他系统对象,如过程、视图等。
【解决方案6】:

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

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

【讨论】:

  • 我知道原始发帖人用“sql-server”标记了这个问题,但这可能对希望在 MySQL 中执行此操作的人有用。事实上,当我在谷歌上搜索这个问题的 MySQL 解决方案时,我发现了这个问题,所以我现在在这里分享我在阅读其中一个答案后提出的解决方案。
【解决方案7】:

我只需对@NoDisplayName 的答案做一个小改动,在TABLE_NAME 列上使用QUOTENAME(),还包括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;

【讨论】:

  • 如果不需要跨 rdbms 的可移植性,我通常会坚持使用 [sys] 模式视图。 stackoverflow.com/a/3654313/251174
  • @swasheck 感谢您提供非常有趣的链接。我已经使用 sys 架构视图更新了答案。
  • 您可以使用 Schema_name() 函数来获取架构名称,而不是加入msdn.microsoft.com/en-us/library/ms175068.aspx
  • @NoDisplayName 仅仅因为你可以,并不意味着你应该...blogs.sqlsentry.com/aaronbertrand/…
  • @AaronBertrand - 我认为这可能是一个更好的方法。感谢您指出。
【解决方案8】:

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

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

【讨论】:

    【解决方案9】:

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

    【讨论】:

      【解决方案10】:

      使用以下脚本将drop全部constraints

      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 数据库中对我有用!

      【讨论】:

        【解决方案11】:

        我知道这个问题很老了,但每次我需要这段代码时..顺便说一下,如果你有表和视图以及函数和过程,你可以通过这个脚本将它全部删除.. 那我为什么要发布这个脚本??因为如果你删除所有表,你将需要删除所有视图,如果你有函数和过程,你也需要删除它
        我希望它会帮助别人

        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
        

        【讨论】:

          【解决方案12】:

          对我来说,我只是这样做

          
          DECLARE @cnt INT = 0;
          
          WHILE @cnt < 10 --Change this if all tables are not dropped with one run
          BEGIN
          SET @cnt = @cnt + 1;
          EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"
          END
          
          

          【讨论】:

            【解决方案13】:

            如果你使用 oracle 或 sqlite,我会为所有表循环:

            FOR i IN (SELECT ut.table_name
                          FROM USER_TABLES ut) LOOP
                EXECUTE IMMEDIATE 'drop table '|| i.table_name ||' CASCADE CONSTRAINTS ';
              END LOOP;
            

            【讨论】:

              猜你喜欢
              • 2019-09-28
              • 1970-01-01
              • 2014-07-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多