T-SQL 删除所有表

Posted

技术标签:

【中文标题】T-SQL 删除所有表【英文标题】:T-SQL Drop all tables 【发布时间】:2017-06-14 14:20:08 【问题描述】:

我正在尝试删除数据库中的所有表,而不必以正确的顺序进行操作。从我读过的内容来看,运行 NOCHECK 命令将阻止检查外键。但是,即使在运行之后,尝试删除第一个表时仍然会出错。

无法删除对象“dbo.TABLENAME”,因为它被 外键约束

我之前已经看到这个问题得到了成功的回答,所以我不明白我正在做的事情有什么不同。这是在 SQL Server 2008 R2 上运行的。

BEGIN TRANSACTION

--get current list of tables
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Dropped Table'
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'


--disable constraint checking in all tables
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' NOCHECK CONSTRAINT ALL; '
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'
select @sql
Exec sp_executesql @sql

--disable all constraints (this also didn't work)
--EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"


--drop all tables
SET @sql = ''
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'
select @sql
Exec sp_executesql @sql


--check current list, should be empty
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Tables'
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'

ROLLBACK TRANSACTION

更新 1

我删除了约束禁用代码来代替约束删除代码,但它给出了错误。

--drop all constraints
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' +QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' DROP CONSTRAINT ' + ctu.CONSTRAINT_NAME + ';'
FROM sys.tables t
    JOIN sys.schemas s
        ON t.[schema_id] = s.[schema_id]
    INNER JOIN EOS_DEV.INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE as ctu
        ON ctu.TABLE_SCHEMA = s.name AND ctu.TABLE_NAME = t.name
WHERE  t.type = 'U'
Exec sp_executesql @sql

表正在引用约束“[CONSTRAINT_NAME]” '[TABLE_NAME]',外键约束'[FK_NAME]'

如何修改此查询以便只针对 FK 约束?

【问题讨论】:

我会先删除所有约束,然后尝试删除表。 @Praveen 不是整个问题如何在不删除约束的情况下使用 NOCHECK 删除表?我认为用户知道他们可以先放弃约束...... 你试过只用一张桌子吗?运行exec sp_MSforeachtable @command1='alter table ? nocheck constraint all' 并删除一张表。它应该可以工作。 我会尝试设置一个循环来继续运行 exec sp_MSforeachtable 'Drop Table ?'检查错误返回 0。每次迭代都会删除引用表。从未真正编写过循环,但通常如果我想删除所有表,我只是一遍又一遍地执行该命令,最终它们都被删除了。 【参考方案1】:

感谢大家的帮助。我更新了我的查询,现在可以确认它能够不加选择地删除所有表。我还添加了一个部分来删除所有存储的过程以增加一点风味。

BEGIN TRANSACTION

--get current list of tables
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Dropped Table'
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'

--drop all constraints
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' +QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' DROP CONSTRAINT ' + tc.CONSTRAINT_NAME + ';'
FROM sys.tables t
    JOIN sys.schemas s
        ON t.[schema_id] = s.[schema_id]
    INNER JOIN EOS_DEV.INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
        ON tc.TABLE_SCHEMA = s.name AND tc.TABLE_NAME = t.name
WHERE t.type = 'U'
    AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
Exec sp_executesql @sql

--drop all tables
SET @sql = ''
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

--drop all stored procs
SET @sql = ''
SELECT @sql += 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + ']'
FROM sys.procedures as p 
where p.is_ms_shipped = 0
    AND p.type = 'P'
Exec sp_executesql @sql

ROLLBACK TRANSACTION

【讨论】:

【参考方案2】:

将 FK 设置为 NOCHECK 将允许您插入、更新或删除违反约束的行。它不允许您 DROP 或 TRUNCATE 目标表。 例如:

use tempdb

create table a(id int primary key)

create table b(id int primary key, aid int references a)

alter table b nocheck constraint all

insert into b(id,aid) values (1,1) --succeeds because of nocheck

drop table a --fails
--Msg 3726, Level 16, State 1, Line 11
--Could not drop object 'a' because it is referenced by a FOREIGN KEY constraint.

【讨论】:

感谢您澄清出了什么问题,但这并没有提供解决方案。【参考方案3】:

你必须让这件事变得如此困难吗?为什么不只恢复一个空数据库(或只包含您的模式和所需的任何“默认”行的数据库)?

【讨论】:

我缺乏访问权限,不想为 DEV 编写正式的实施计划。

以上是关于T-SQL 删除所有表的主要内容,如果未能解决你的问题,请参考以下文章

t-SQL 更新表以删除重叠的时间范围

T-SQL:删除所有重复的行但保留一个[重复]

T-SQL语句3

如果存在,则 T-SQL 删除类型 [重复]

T-SQL Recipes之删除重复行

数据库表的管理(使用T-SQL语句)