2010-09-10 105 views

回答

132

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 
+0

我要..我能够删除,但不能截断。 – Marcel 2012-10-08 08:54:41

+11

在DELETE FROM之后执行'EXEC sp_MSForEachTable'DBCC CHECKIDENT(''?'',RESEED,0)''将所有标识列重置为0也可能有意义。 – 2013-11-07 21:46:49

+0

它始终是一个良好开端那天你会发现6行代码取代了100个删除语句!此方法在SQL 2014 Express上无任何问题。 – Tommy 2015-04-08 14:21:23

35

通常我只会用无证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 

参见:Delete all data in database (when you have FKs)

+1

我不认为这有效。看起来卡伦德莱尼无意中负责开始这个想法。 [在这里她澄清](http://www.eggheadcafe.com/software/aspnet/29927698/cant-truncate-table.aspx)“您必须删除引用约束以截断表。” – 2010-10-02 00:38:51

+0

Martin我刚刚在Adventureworks DB中跑了2秒,没出现问题 – SQLMenace 2010-10-02 00:45:18

+0

这绝对不适合我这里。 '创建数据库测试; GO使用测试;创建表t1(我int主键)创建表t2(我诠释主键,诠释引用t1)' – 2010-10-02 01:19:35

5

它通常是更快脚本出数据库中的所有对象,并创建一个空的,那从表中删除或截断表。

10
/* 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 
+0

这实际上对我有用 – 2016-08-17 06:41:42

12

我知道这是晚了,但我同意AlexKuznetsov的建议,脚本的数据库,而不是通过从表中清除数据的麻烦去。如果TRUNCATE解决方案无法正常工作,并且您碰巧拥有大量数据,则发布(记录日志)DELETE语句可能需要很长时间,并且您将留下尚未重新编码的标识符(即INSERT语句为一个带有IDENTITY列的表格会为您提供50000的ID而不是1的ID)。

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

enter image description here

点击Next跳过向导打开屏幕,然后选择哪些对象想脚本:

enter image description here

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

enter image description here

该向导会显示摘要,您可以使用验证一切正常,然后点击'完成'关闭。

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 
-- .... 
-- .... 
-- .... 
4
  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语句。从引用的表开始然后引用那些

  • 复制DELETE FROM语句,并且一旦运行它们

  • 启用触发器

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

    begin transaction 
    commit; 
    
  • +0

    这对我不起作用,递归查询最终以循环结束。也许是因为自尊。 – 2016-01-27 10:32:23

    0
    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 
    
    相关问题