【发布时间】:2011-04-10 21:30:40
【问题描述】:
如何从我的数据库的所有表中删除所有记录?我可以使用一条 SQL 命令来完成,还是需要一张表执行一条 SQL 命令?
【问题讨论】:
标签: sql sql-server delete-row multi-table-delete
如何从我的数据库的所有表中删除所有记录?我可以使用一条 SQL 命令来完成,还是需要一张表执行一条 SQL 命令?
【问题讨论】:
标签: sql sql-server delete-row multi-table-delete
结合现有答案中的所有优秀技巧以及更多技巧,我编写了这个脚本。它更全面一些,应该更有效率。
在删除步骤之前的脚本:
对于删除步骤,它会在可能的情况下截断(更快),或者使用 tabblock 提示删除(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
【讨论】:
为自己节省一些时间/空间,并尽可能使用 TRUNCATE 而不是 DELETE, 如果您拥有庞大的数据库,则不会使您的日志文件膨胀。
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK 约束所有' 去吧
执行 sp_MSForEachTable ' IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1 从中删除? 别的 截断表?'
EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL' 去吧
【讨论】:
作为替代答案,如果您使用 Visual Studio SSDT 或 Red Gate Sql Compare,您可以简单地运行模式比较,编写脚本,删除旧数据库(可能先进行备份,以防万一您将需要该数据),然后使用比较工具创建的脚本创建一个新数据库。虽然在非常小的数据库上这可能需要更多的工作,但在非常大的数据库上,简单地删除数据库然后处理数据库上可能存在的不同触发器和约束会更快。
【讨论】:
可以,一行代码就可以删除
SELECT 'TRUNCATE TABLE ' + d.NAME + ';'
FROM sys.tables d
WHERE type = 'U'
【讨论】:
下面是我用来从 SQL Server 数据库中删除所有数据的脚本
------------------------------------------------------------
/* Use database */
-------------------------------------------------------------
use somedatabase;
GO
------------------------------------------------------------------
/* Script to delete an repopulate the base [init database] */
------------------------------------------------------------------
-------------------------------------------------------------
/* Procedure delete all constraints */
-------------------------------------------------------------
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'sp_DeleteAllConstraints' AND type = 'P')
DROP PROCEDURE dbo.sp_DeleteAllConstraints
GO
CREATE PROCEDURE sp_DeleteAllConstraints
AS
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
GO
-----------------------------------------------------
/* Procedure delete all data from the database */
-----------------------------------------------------
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'sp_DeleteAllData' AND type = 'P')
DROP PROCEDURE dbo.sp_DeleteAllData
GO
CREATE PROCEDURE sp_DeleteAllData
AS
EXEC sp_MSForEachTable 'DELETE FROM ?'
GO
-----------------------------------------------
/* Procedure enable all constraints */
-----------------------------------------------
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'sp_EnableAllConstraints' AND type = 'P')
DROP PROCEDURE dbo.sp_EnableAllConstraints
GO
-- ....
-- ....
-- ....
【讨论】:
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
EXEC sp_MSFOREACHTABLE 'SELECT * FROM ?'
GO
【讨论】:
SQLMenace 的解决方案对我有用,只是对删除数据的方式稍作调整 - DELETE FROM 而不是 TRUNCATE。
-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'DELETE FROM ?'
GO
-- enable referential integrity again
EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
GO
【讨论】:
EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)' 将所有标识列重置回 0 也可能有意义。
DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'...。为我工作:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
首先你必须禁用所有的触发器:
sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
运行这个脚本:(取自post谢谢@SQLMenace)
SET NOCOUNT ON
GO
SELECT 'USE [' + db_name() +']';
;WITH a AS
(
SELECT 0 AS lvl,
t.object_id AS tblID
FROM sys.TABLES t
WHERE t.is_ms_shipped = 0
AND t.object_id NOT IN (SELECT f.referenced_object_id
FROM sys.foreign_keys f)
UNION ALL
SELECT a.lvl + 1 AS lvl,
f.referenced_object_id AS tblId
FROM a
INNER JOIN sys.foreign_keys f ON a.tblId = f.parent_object_id
AND a.tblID <> f.referenced_object_id
)
SELECT
'Delete from ['+ object_schema_name(tblID) + '].[' + object_name(tblId) + ']'
FROM a
GROUP BY tblId
ORDER BY MAX(lvl),1
此脚本将按正确顺序生成DELETE 语句。从引用的表开始,然后引用那些
复制DELETE FROM 语句并运行一次
启用触发器
sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
提交更改:
begin transaction
commit;
【讨论】:
我知道这已经晚了,但我同意 AlexKuznetsov 为数据库编写脚本的建议,而不是经历从表中清除数据的麻烦。如果TRUNCATE 解决方案不起作用,并且您恰好有大量数据,则发出(记录)DELETE 语句可能需要很长时间,并且您将留下尚未重新植入的标识符(即将INSERT 语句插入到具有IDENTITY 列的表中会得到一个ID 50000 而不是ID 1)。
要编写整个数据库的脚本,在 SSMS 中,右键单击数据库,然后选择 TASKS -> Generate scripts:
单击Next 跳过向导打开屏幕,然后选择要编写脚本的对象:
在Set scripting options 屏幕中,您可以选择脚本设置,例如是为所有对象生成 1 个脚本,还是为各个对象生成单独的脚本,以及是以 Unicode 还是 ANSI 保存文件:
向导将显示一个摘要,您可以使用它来验证一切是否符合要求,然后单击“完成”关闭。
【讨论】:
/* 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
/* 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
【讨论】:
将数据库中的所有对象编写脚本并创建一个空的对象来删除或截断表通常要快得多。
【讨论】:
通常我只会使用未记录的 proc sp_MSForEachTable
-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'
GO
-- enable referential integrity again
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
【讨论】:
create database testing; GO use testing; create table t1 (i int primary key) create table t2(i int primary key,p int references t1)