【问题标题】:How to drop all tables in a SQL Server database?如何删除 SQL Server 数据库中的所有表?
【发布时间】:2011-12-09 00:30:55
【问题描述】:

我正在尝试编写一个完全清空 SQL Server 数据库的脚本。这是我目前所拥有的:

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

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

命令成功完成。

但是当我刷新表格列表时,它们都还在。我做错了什么?

【问题讨论】:

  • 如果此页面上的解决方案都不起作用,也许您忘记了:USE [DatabaseName] GO
  • 删除?将从表中删除记录。您应该使用 DROP TABLE ?,但是由于其他原因,这将不起作用。
  • 必读:xkcd.com/327

标签: sql-server sql-server-2008 ssms sp-msforeachtable


【解决方案1】:

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

我是这样一步一步做的:

  1. 在数据库树中选择“表”(对象资源管理器)
  2. 按 F7 打开对象资源管理器详细信息视图
  3. 在此视图中选择必须删除的表(在本例中为全部)
  4. 一直按住 Delete 键,直到所有表都被删除(由于键约束/依赖关系导致的错误数量,您可以重复多次)

【讨论】:

  • 我无法让 sp_msforeachtable 在 Azure sql 数据库上工作。我猜他们没有将它包含在 Azure 中。此解决方案效果很好,非常适合使用 EF 迁移模拟或进行大量更改(重新开始)。
  • 不考虑 FK/订单。
  • 如果你只需要在这里和那里做的话,这是一个方便的方法,如果你经常这样做,脚本可能会更好。
  • @Josh 不考虑订单,但如果您在“删除”对话框中继续按“确定”,它将继续删除所有可以删除的表,最终将删除所有表。
  • 使用 Designer 的完美解决方案
【解决方案2】:

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

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

您可以找到帖子here。这是 Groker 的帖子。

【讨论】:

  • 为什么当您尝试使用 BEGIN-END 块将整个代码块包装在 IF 语句中时,它会抱怨光标?
  • 我收到错误Could not find stored procedure 'sp_MSForEachTable'.
  • 如果您的表(带有约束)与dbo 不同,则此答案不起作用。如果您有自定义架构,则需要将 sql 更改为:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
  • sp_MSforeachtable 在 Azure 中不可用。请改用@CountZero 的答案。
  • 在网上找到了这个参考资料(不是我的):A Copy Of sp_MSforeachtable Stored Procedure For Azure, Uses sp_MSforeach_worker : gist.github.com/metaskills/893599.
【解决方案3】:

在 SSMS 中:

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

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

【讨论】:

  • 如果您不想删除数据库(在我的情况下,我不想这样做,因为我需要拨打支持电话来创建它)然后使用“选择特定的数据库对象' 并选择您希望删除的所有对象类型。
  • 这是最简单的方法。
  • 这肯定是答案!
【解决方案4】:

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

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

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

【讨论】:

  • 在天蓝色上像魔术一样工作。比通过 VS 的 UI 删除要快得多
  • 工作就像一个魅力!
【解决方案5】:

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

EXEC sp_msforeachtable 'drop table [?]'

【讨论】:

  • 这似乎解决了没有任何错误的问题,但现在我遇到了约束错误。我的NOCHECK CONSTRAINT 行的语法错了吗?
  • 我在一张带有 FK 的快速 2 张桌子上使用了它,它奏效了。执行 sp_msforeachtable 'ALTER TABLE ? NOCHECK 约束所有'
  • 这仅在我删除方括号后对我有用:EXEC sp_msforeachtable 'drop table ?'。
  • 在 SQL Server 上,如果任何表名包含奇数字符或空格,则需要括号。我不知道有哪个版本的 SQL Server 不支持对象名称两边的括号。
  • 在 SQL Server 2012 (11.x) 上,我还必须删除方括号。
【解决方案6】:
/* 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

【讨论】:

  • 在 SQL Azure 中工作 :) sp_MSforeachtable 在那里不起作用
  • 请注意,如果您有非 dbo 模式(例如,如果您使用 Hangfire),这将失败
【解决方案7】:

你几乎是对的,改用:

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.

表示所有表都已成功删除。

【讨论】:

    【解决方案8】:

    又短又甜:

    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
    

    【讨论】:

    • 我不得不将 sp_msforeachtable 替换为 sp_MSforeachtable 并强烈建议添加 use yourdatabase 作为第一行。像魅力一样工作。
    • 又短又甜!谢谢。
    【解决方案9】:

    似乎命令应该没有方毯

    EXEC sp_msforeachtable 'drop table ?'
    

    【讨论】:

      【解决方案10】:

      禁食方式是:

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

      【讨论】:

      • 这是迄今为止最快、不易出错的方法。这应该是公认的答案。
      • 可能是因为表多的时候会崩溃
      • 此选项似乎不再可用
      【解决方案11】:

      准点!!

      您可以使用以下查询从数据库中删除所有表

      EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

      编码愉快!

      【讨论】:

      • 多次执行。最后被删除了所有表。
      • 我认为你只需要做一次。
      • 我有多个具有外键的表。在一次执行中,它没有工作。但是多次执行,我必须删除所有表。
      【解决方案12】:

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

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

      【讨论】:

        【解决方案13】:

        删除整个数据库然后重新创建它怎么样?这对我有用。

        DROP DATABASE mydb;
        CREATE DATABASE mydb;
        

        【讨论】:

        • 你不需要在中间炸掉 mdf 和 ldf 文件吗?
        • 我正在使用网络托管服务提供商,对此我不太确定。我认为当您删除数据库时,这些文件将被自动删除,除非您处于离线状态。
        • 这真的取决于具体情况。就我而言,我没有存储过程,这种方法对我来说很好。我不会编写跨越几十行的复杂代码,而两行代码就可以了。我认为我的回答不能证明投反对票是合理的,因为我正在向特定的用户组提供建议。
        【解决方案14】:

        与 dbo + ipv6_database_firewall_rules 条件不同的架构中的 Azure SQL + 表(带约束)。

        这是https://stackoverflow.com/a/43128914/4510954 答案的一个小扩展。

        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 ' + CONSTRAINT_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' AND TABLE_NAME != 'ipv6_database_firewall_rules'))
        BEGIN
            SELECT TOP 1 @sql=('DROP TABLE ' + CONSTRAINT_SCHEMA  + '.[' + TABLE_NAME + ']')
            FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
            WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'
            EXEC(@sql)
            PRINT @sql
        END
        

        【讨论】:

        • 这也适用于 Azure SQL 数据库,谢谢!
        【解决方案15】:

        我知道这是一篇旧文章,但我已经在众多数据库上尝试了这里的所有答案,我发现它们有时都有效,但并非所有时间都适用于各种(我只能假设)SQL 的怪癖服务器。

        最终我想出了这个。我已经在任何地方(一般来说)我都可以测试它并且它可以工作(没有任何隐藏的存储过程)。

        注意主要是在 SQL Server 2014 上。(但我尝试过的大多数其他版本似乎也运行良好)。

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

        获取计数并使用它进行迭代似乎总是适用于我测试的所有内容。

        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
        

        【讨论】:

          【解决方案16】:

          对于临时表,它有点复杂,因为可能有一些外键和例外:

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-15
            • 1970-01-01
            相关资源
            最近更新 更多