在SQL Server数据库中删除所有数据

148
如何删除数据库中所有表的所有记录?我需要使用一个 SQL 命令还是每个表都需要一个 SQL 命令?
13个回答

0

如果可能的话,使用TRUNCATE而不是DELETE可以节省时间/空间,而且在你有一个巨大的数据库的情况下,不会使日志文件膨胀。

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable '
        IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1
            DELETE FROM ?
        ELSE
            TRUNCATE TABLE ?'

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

0

结合现有答案中的所有优秀技巧以及其他一些技巧,我编写了这个脚本。它更加全面,效率应该更高。

在删除步骤之前,脚本会执行以下操作:

  • 禁用触发器(如果您有任何删除触发器,则特别重要)
  • 禁用约束检查
  • 禁用非聚集索引(否则它们将逐行与表一起被删除)

对于删除步骤,它将尽可能地截断(速度更快),否则使用tablock提示进行删除(tablock仅对堆表有帮助,并且由于我们无论如何都会收缩文件,因此在这里可能不会添加任何内容)。

在删除步骤之后,脚本将执行以下操作:

  • 重建/启用所有索引(它们已经为空了)
  • 启用约束检查
  • 启用触发器
  • 重新生成标识列
  • 收缩数据库文件

删除数据库中的所有数据:

use [your_database]
go

exec sp_MSforeachtable 'alter table ? disable trigger all'
go

exec sp_MSforeachtable 'alter table ? nocheck constraint all'
go

-- Disable enabled nonclustered indices
declare @script nvarchar(max)
declare cr cursor fast_forward read_only for
select 'alter index ' + quotename(i.name) + ' on ' + quotename(schema_name(t.schema_id))+'.'+ quotename(t.name) + ' disable'
from sys.indexes i inner join sys.tables t on i.object_id = t.object_id
where i.type_desc = 'nonclustered' and i.name is not null and i.is_disabled = 0;
open cr
fetch next from cr into @script
while @@fetch_status = 0
begin
    execute sp_executesql @script 
    fetch next from cr into @script
end
close cr
deallocate cr
go

exec sp_MSforeachtable 'set quoted_identifier on; if objectproperty(object_id(''?''), ''TableHasForeignRef'') = 1 delete from ? with (tablock) else truncate table ?'
go

exec sp_MSforeachtable 'set quoted_identifier on; alter index all on ? rebuild';
go

exec sp_MSforeachtable 'alter table ? with check check constraint all'
go

exec sp_MSforeachtable 'alter table ? enable trigger all'
go

-- Re-seed identity columns
exec sp_MSforeachtable 'if objectproperty(object_id(''?''), ''TableHasIdentity'') = 1 dbcc checkident(''?'', reseed, 0)'
go

-- Shrink the database files
declare @db_name nvarchar(200) = db_name()
dbcc shrinkdatabase (@db_name, 0);  
go 

-1

是的,可以用一行代码删除

SELECT 'TRUNCATE TABLE ' + d.NAME + ';' 
FROM   sys.tables d 
WHERE  type = 'U' 

这给了我一个新表,其中包含每个表的truncate语句。它实际上并没有删除任何内容,不幸的是它没有先处理掉删除约束的问题。太糟糕了,我希望有一个像这样的答案,而不使用sp_MSForEachTable(这在我的Azure SQL Server中不存在)! - Pac0
是的。真的。它创建了所有表的截断脚本。使用该脚本删除表数据。 - Buddhika De Silva
这个解决方案仅在没有任何关系的情况下才有效,因为它无法保证表以正确的顺序被删除。此外,如果有任何与数据删除相关的触发器,可能会产生意想不到的后果。 - dmoore1181

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接