【问题标题】:How to delete all tables from db? Cannot delete from sys.tables如何从数据库中删除所有表?无法从 sys.tables 中删除
【发布时间】:2011-06-06 07:04:06
【问题描述】:

如何以任何方式执行此查询:

delete from sys.tables where is_ms_shipped = 0

发生的事情是,我执行了一个非常大的查询,但我忘记在其上放置 USE 指令,现在我的主数据库上有无数个表,不想一个一个地删除它们。

更新:这是一个全新的数据库,所以我不必关心任何以前的数据,我想要达到的最终结果是将主数据库重置为出厂。

【问题讨论】:

  • sys.* 对象是系统目录视图,允许您查询(但不能操作)数据库中对象的视图。要创建或删除对象,请使用相应的 SQL 命令。
  • 是的,我意识到了这一点。我一直在寻找任何方法来进行更改。

标签: sql-server sql-server-2008 adhoc sys sql-server-2008r2-express


【解决方案1】:

如果这是一次性问题,请使用 SQL Server Management Studio 删除表。

如果您必须非常非常运行脚本,请谨慎使用:

EXEC sp_msforeachtable 'DROP TABLE ?'

【讨论】:

  • @Shimmy:查看更新的答案。这将删除数据库中的所有用户表,除非需要首先删除外键。但是,它不会删除用户、同义词等。
  • 另请阅读我的问题中的查询,我不想删除所有表,我只想删除我意外添加的表,而不是安装附带的表。
  • @Shimmy: sp_msforeachtable 每个 user 表的进程。它不包括系统表。
  • 它不起作用,有关系,它不会删除它们。
  • @Shimmy - 你不能在没有更多表格之前循环运行脚本吗? WHILE EXISTS(SELECT * FROM sys.tables where is_ms_shipped = 0) EXEC sp_MSforeachtable 'DROP TABLE ?'
【解决方案2】:

我过去使用的一种非常简单且相对简单的方法是查询系统表/信息架构(取决于确切的要求)并让它输出我想要执行的命令列表作为结果集.回顾一下,复制和粘贴,运行 - 对于一次性工作来说既快速又简单,而且由于您仍然手动点击破坏性位上的按钮,因此 (恕我直言) 更难错误地丢弃东西。

例如:

select 'drop table ' + name + ';', * from sys.tables where is_ms_shipped = 0

【讨论】:

    【解决方案3】:

    没有备份? :-)

    一种方法可能是在 Visual Studio 中创建一个带有初始数据库导入的数据库项目。然后删除表并将项目同步回数据库。您可以使用这种方法进行大量删除,同时通过提交阶段和 UI 进行“缓冲”。

    相当确定上述方法也可以用于处理表关系(尽管我在“主”空间中没有尝试过)。我还建议使用 VS DB 项目(或其他允许模式比较和同步的数据库管理工具)以使将来的生活更轻松,并允许版本化(例如使用 SCM)模式更改跟踪。

    哦,不管做什么,请先创建一个备份。如果不出意外,这是很好的培训:-)

    【讨论】:

      【解决方案4】:

      不是很优雅,但这是一次性任务。

      WHILE EXISTS(SELECT * FROM sys.tables where is_ms_shipped = 0) 
            EXEC sp_MSforeachtable 'DROP TABLE ?'
      

      在这个简单的测试中运行良好(在第一次尝试失败后在第二个循环中清除 a,然后继续删除 b

      create table a
      (
      a int primary key
      )
      go
      
      create table b
      (
      a int references a (a)
      )
      
      insert into a values (1)
      
      insert into b values (1)
      

      【讨论】:

        【解决方案5】:

        我做的最简单和最短的方法是:

        How to Rebuild System Databases in SQL Server 2008

        这里所有其他答案的问题是它不起作用,因为有相关的表并且它拒绝执行。

        这个,不仅有效,而且实际上是我正在寻找的:“重置为出厂默认设置”,如问题中所述。
        这也将删除所有内容,而不仅仅是表格。

        【讨论】:

          【解决方案6】:

          这段代码可能会更好,但我在编写它时尽量保持谨慎。我认为在您承诺删除表之前,很容易遵循易​​于调整的测试。

          DECLARE 
              @Prefix VARCHAR(50),
              @TableName NVARCHAR(255),
              @SQLToFire NVARCHAR(350)
          
          SET @Prefix = 'upgrade_%'
          
          WHILE EXISTS(
              SELECT
                  name
              FROM
                  sys.tables
              WHERE
                  name like @Prefix
              )
          BEGIN
              SELECT
                  TOP 1   --This query only iterates if you are dropping tables
                  @TableName = name
              FROM
                  sys.tables
              WHERE
                  name like @Prefix
          
              SET @SQLToFire = 'DROP TABLE ' + @TableName
          
              EXEC sp_executesql @SQLToFire;
          END
          

          【讨论】:

            【解决方案7】:

            我做了一些非常相似的事情,我最终做的是使用 Tasks--> 脚本数据库来仅为最初预期数据库的所有数据库对象删除脚本。这意味着我应该在其上运行巨型脚本的数据库,而我确实在其上运行过它。确保在高级选项中包含 IF Exists,然后针对 master 和 BAM 运行该脚本,删除存在于原始目标数据库中的所有内容,也存在于 master 中,留下差异,这应该是原始 master 项目。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-09-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-29
              • 2017-06-30
              相关资源
              最近更新 更多