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


Answers:


194

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

Me To ..我能够删除,但无法截断。
马塞尔(Marcel)2012年

17
这也可能是有意义的做EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'了DELETE FROM之后的所有标识列重置为0
乔纳森修改

1
找到6行代码来代替100条delete语句的一天总是一个好的开始!此方法在SQL 2014 Express上没有问题。
汤米

1
不要忘了禁止触发器的藏汉
埃德温Stoteler

10
我遇到错误- DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'...。为我工作:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
卡西

36

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

另请参阅:删除数据库中的所有数据(如果有FK)


1
我认为这行不通。看起来Kalen Delaney在无意中承担了开始这个想法的责任。她在这里澄清 “您必须删除引用约束才能截断表”。
马丁·史密斯,2010年

Martin我2秒钟前刚刚在Adventureworks数据库中运行了它,没有问题
SQLMenace 2010年

它在这里绝对对我不起作用。create database testing; GO use testing; create table t1 (i int primary key) create table t2(i int primary key,p int references t1)
马丁史密斯,

2
尽管被标记为答案,但这不起作用。在外键上设置nocheck约束不允许您在这些表上运行截断命令。您仍然会收到阻止您被截断的错误。
2013年

3
由于存在外键,因此无法使用。我仍然不明白为什么它被接受为答案:/
mounaim 2014年

19
/* 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

有趣的脚本,它没有利用Azure上缺少的,不加注释的存储过程'sp_MSForEachTable'。但是,如果您在[dbo]以外的其他架构上有对象,则需要进行调整。
Pac0

请使用gist.github.com/metaskills/893599在Azure中创建sp_MSForEachTable
Harpal,2018年

16

我知道这已经晚了,但是我同意AlexKuznetsov的建议编写数据库脚本的建议,而不是经历从表中清除数据的麻烦。如果该TRUNCATE解决方案不起作用,并且您碰巧拥有大量数据,则发出(记录)的DELETE语句可能会花费很长时间,并且您将剩下尚未重新INSERT植入的标识符(即,将语句插入到具有一IDENTITY列将让你的50000的ID,而不是1的ID)。

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明

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


请注意,这种方式默认情况下,如果不转到“高级”按钮,您将丢失诸如索引之类的内容。
glautrou

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

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. 运行此脚本:(摘自这篇文章,谢谢@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;

这对我不起作用,递归查询最终陷入循环。也许是因为自我崇敬。
Edwin Stoteler '16

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,则可以简单地运行模式比较,将其编写为脚本,删除旧数据库(可能在需要时首先进行备份,以防万一)该数据),然后使用比较工具创建的脚本创建一个新的数据库。在一个非常小的数据库上,这可能需要更多的工作,而在一个很大的数据库上,简单地删除数据库然后处理可能存在于数据库上的各种触发器和约束将更快。


-1

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

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

这给了我一个新表,每个表都有一个截断语句。它实际上并没有删除任何内容,不幸的是它确实解决了首先删除约束的问题。太糟糕了,我希望能得到这样的答案,而无需使用sp_MSForEachTable(对于我来说,Azure SQL Server不存在)!
Pac0

是。真正。它为所有表创建截断脚本。使用该脚本删除表数据。
Buddhika De Silva

该解决方案仅在没有任何关系的情况下才有效,因为它无法保证以正确的顺序删除表。另外,如果存在删除数据的任何触发器,则可能会造成意想不到的后果。
dmoore1181
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.