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

问题描述 投票:0回答:14

如何删除数据库所有表中的所有记录?我可以用一条 SQL 命令来完成吗?还是每个表都需要一条 SQL 命令?

sql sql-server delete-row multi-table-delete
14个回答
226
投票

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

39
投票

通常我只会使用未记录的过程 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

另请参阅:删除数据库中的所有数据(当您有 FK 时)


22
投票
/* 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

19
投票

我知道这已经晚了,但我同意 AlexKuznetsov 的建议,即编写数据库脚本,而不是经历从表中清除数据的麻烦。如果

TRUNCATE
解决方案不起作用,并且您碰巧拥有大量数据,则发出(记录的)
DELETE
语句可能需要很长时间,并且您将留下尚未重新播种的标识符(即在具有
INSERT
列的表中执行
IDENTITY
语句将为您提供 ID 50000,而不是 ID 1)。

要编写整个数据库的脚本,请在 SSMS 中右键单击数据库,然后选择

TASKS
->
Generate scripts
:

enter image description here

单击

Next
跳过向导打开屏幕,然后选择要编写脚本的对象:

enter image description here

Set scripting options
屏幕中,您可以选择脚本设置,例如是否为所有对象生成 1 个脚本,或为各个对象生成单独的脚本,以及是否以 Unicode 或 ANSI 保存文件:

enter image description here

向导将显示一个摘要,您可以使用它来验证一切是否符合要求,然后单击“完成”关闭。


9
投票
  1. 首先,您必须禁用所有触发器:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
    
  2. 运行此脚本:(取自此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
语句。从引用的表格开始,然后引用表格

  1. 复制

    DELETE FROM
    语句并运行一次

  2. 启用触发器

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
    
  3. 提交更改:

    begin transaction
    commit;
    

5
投票

用脚本编写数据库中的所有对象并创建一个空对象(从表中删除或截断表)通常要快得多。


3
投票

下面是我用来从 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
-- ....
-- ....
-- ....

1
投票
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

0
投票

作为替代答案,如果您使用 Visual Studio SSDT 或可能使用 Red Gate Sql Compare,您可以简单地运行模式比较,编写脚本,删除旧数据库(可能首先进行备份,以防万一您将需要该数据),然后使用比较工具创建的脚本创建一个新数据库。虽然在非常小的数据库上,这可能需要更多工作,但在非常大的数据库上,简单地删除数据库然后处理数据库上可能存在的不同触发器和约束会更快。


0
投票

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

在删除步骤之前,脚本:

  • 禁用触发器(如果您有任何删除触发器,则尤其重要) 触发器)
  • 禁用约束检查
  • 禁用非聚集索引(否则它们会被逐行删除 与桌子)

对于删除步骤,它将在可能的情况下截断(更快),或者使用 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 

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
投票

执行 sys.sp_msforeachtable '更改表? NOCHECK 约束所有' EXEC sys.sp_msforeachtable '删除自?'

EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON;删除自?'

执行 sys.sp_MSForEachTable '更改表?检查所有约束'


0
投票

/* 描述:此脚本将从数据库中删除所有表、视图、函数、存储过程和用户定义类型。 */ 声明@n char(1) 设置@n = char(10)

    declare @stmt nvarchar(max)

    -- procedures
    select @stmt = isnull( @stmt + @n, '' ) +
    'drop procedure [' + schema_name(schema_id) + '].[' + name + ']'
    from sys.procedures


    -- check constraints
    select @stmt = isnull( @stmt + @n, '' ) +
    'alter table [' + schema_name(schema_id) + '].[' + object_name( parent_object_id ) + ']    drop constraint [' + name + ']'
    from sys.check_constraints

    -- functions
    select @stmt = isnull( @stmt + @n, '' ) +
    'drop function [' + schema_name(schema_id) + '].[' + name + ']'
    from sys.objects
    where type in ( 'FN', 'IF', 'TF' )

    -- views
    select @stmt = isnull( @stmt + @n, '' ) +
    'drop view [' + schema_name(schema_id) + '].[' + name + ']'
    from sys.views

    -- foreign keys
    select @stmt = isnull( @stmt + @n, '' ) +
    'alter table [' + schema_name(schema_id) + '].[' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
    from sys.foreign_keys

    -- tables
    select @stmt = isnull( @stmt + @n, '' ) +
    'drop table [' + schema_name(schema_id) + '].[' + name + ']'
    from sys.tables

    -- user defined types
    select @stmt = isnull( @stmt + @n, '' ) +
    'drop type [' + schema_name(schema_id) + '].[' + name + ']'
    from sys.types
    where is_user_defined = 1


    exec sp_executesql @stmt

-1
投票

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

SELECT 'TRUNCATE TABLE ' + d.NAME + ';' 
FROM   sys.tables d 
WHERE  type = 'U' 
© www.soinside.com 2019 - 2024. All rights reserved.