Löschen Sie alle Daten in der SQL Server-Datenbank


Antworten:


194

Die Lösung von SQLMenace funktionierte für mich mit einer kleinen Änderung, wie Daten gelöscht werden - DELETE FROMstatt 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

Ich an .. Ich konnte löschen, aber nicht abschneiden.
Marcel

17
Es könnte auch sinnvoll sein, EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'nach dem LÖSCHEN VON eine zu machen, um alle Identitätsspalten auf 0 zurückzusetzen.
Jonathan Amend

1
Es ist immer ein guter Start in den Tag, wenn Sie 6 Codezeilen finden, die Hunderte von Löschanweisungen ersetzen! Diese Methode funktioniert problemlos in SQL 2014 Express.
Tommy

1
Vergessen Sie nicht, auch die Trigger zu deaktivieren
Edwin Stoteler

10
Ich habe Fehler bekommen - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Für mich hat gearbeitet:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Normalerweise verwende ich nur den undokumentierten Prozess 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

Siehe auch: Löschen Sie alle Daten in der Datenbank (wenn Sie FKs haben)


1
Ich denke nicht, dass das funktioniert. Es sieht so aus, als ob Kalen Delaney versehentlich dafür verantwortlich war, diese Idee auf den Weg zu bringen. Hier stellt sie klar: "Sie müssen die Referenzierungsbeschränkung löschen, um die Tabelle abzuschneiden."
Martin Smith

Martin Ich habe es gerade vor 2 Sekunden in der Adventureworks-
Datenbank

Bei mir funktioniert das hier definitiv nicht. create database testing; GO use testing; create table t1 (i int primary key) create table t2(i int primary key,p int references t1)
Martin Smith

2
Dies funktioniert nicht, obwohl es als Antwort markiert ist. Durch Festlegen der nocheck-Einschränkung für Fremdschlüssel können Sie keine Kürzungsbefehle für diese Tabellen ausführen. Sie erhalten weiterhin Fehler, die Sie am Abschneiden hindern.
Vierter

3
Dies funktioniert aufgrund des Vorhandenseins von Fremdschlüsseln nicht. Ich kann immer noch nicht verstehen, warum es als Antwort akzeptiert wurde: /
mounaim

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

interessantes Skript, das nicht den undokumentierten gespeicherten Prozess 'sp_MSForEachTable' verwendet, der in Azure fehlt. Muss jedoch angepasst werden, wenn Sie Objekte in einem anderen Schema als [dbo] haben.
Pac0

Bitte verwenden Sie gist.github.com/metaskills/893599 , um sp_MSForEachTable in Azure
Harpal

16

Ich bin mir bewusst, dass dies spät ist, aber ich stimme AlexKuznetsovs Vorschlag zu, die Datenbank zu skripten, anstatt die Daten aus den Tabellen zu entfernen. Wenn die TRUNCATELösung nicht funktioniert und Sie zufällig über eine große Datenmenge verfügen, kann das Ausgeben von (protokollierten) DELETEAnweisungen lange dauern, und Sie erhalten Bezeichner, die nicht neu gesetzt wurden (dh eine INSERTAnweisung in eine Tabelle mit Eine IDENTITYSpalte würde Ihnen eine ID von 50000 anstelle einer ID von 1) geben.

Um eine ganze Datenbank zu skripten, klicken Sie in SSMS mit der rechten Maustaste auf die Datenbank und wählen Sie TASKS-> Generate scripts:

Geben Sie hier die Bildbeschreibung ein

Klicken Sie Nextauf, um den Startbildschirm des Assistenten zu überspringen, und wählen Sie dann aus, welche Objekte Sie skripten möchten:

Geben Sie hier die Bildbeschreibung ein

Auf dem Set scripting optionsBildschirm können Sie Einstellungen für die Skripterstellung auswählen, z. B. ob 1 Skript für alle Objekte oder separate Skripte für die einzelnen Objekte generiert werden sollen und ob die Datei in Unicode oder ANSI gespeichert werden soll:

Geben Sie hier die Bildbeschreibung ein

Der Assistent zeigt eine Zusammenfassung an, mit der Sie überprüfen können, ob alles wie gewünscht ist, und schließen, indem Sie auf "Fertig stellen" klicken.


Seien Sie vorsichtig, auf diese Weise verlieren Sie standardmäßig Dinge wie Indizes, wenn Sie nicht auf die Schaltfläche "Erweitert" klicken.
Glautrou

6
  1. Zuerst müssen Sie alle Trigger deaktivieren:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Führen Sie dieses Skript aus: (Entnommen aus diesem Beitrag Vielen Dank an @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
    

Dieses Skript erzeugt DELETEAnweisungen in der richtigen Reihenfolge. Ausgehend von referenzierten Tabellen und dann von referenzierenden Tabellen

  1. Kopieren Sie die DELETE FROMAnweisungen und führen Sie sie einmal aus

  2. Trigger aktivieren

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Übernehmen Sie die Änderungen:

    begin transaction
    commit;
    

Dies funktioniert bei mir nicht, die rekursive Abfrage endet in einer Schleife. Vielleicht wegen Selbstachtung.
Edwin Stoteler

5

In der Regel ist es viel schneller, alle Objekte in der Datenbank auszuskripten und ein leeres Objekt zu erstellen, das aus Tabellen gelöscht oder abgeschnitten werden kann.


3

Unten ein Skript, mit dem ich alle Daten aus einer SQL Server-Datenbank entfernt habe

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

Als alternative Antwort können Sie, wenn Sie Visual Studio SSDT oder möglicherweise Red Gate Sql Compare verwenden, einfach einen Schema-Vergleich durchführen, ein Skript erstellen und die alte Datenbank löschen (möglicherweise erstellen Sie zuerst eine Sicherung, falls es einen Grund gibt, den Sie benötigen diese Daten) und erstellen Sie dann eine neue Datenbank mit dem vom Vergleichstool erstellten Skript. Während dies in einer sehr kleinen Datenbank möglicherweise mehr Arbeit bedeutet, ist es in einer sehr großen Datenbank viel schneller, die Datenbank einfach zu löschen, als sich mit den verschiedenen Auslösern und Einschränkungen zu befassen, die möglicherweise in der Datenbank vorhanden sind.


-1

Ja, es ist möglich, mit einer einzigen Codezeile zu löschen

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

Dies gibt mir eine neue Tabelle mit einer abgeschnittenen Anweisung für jede Tabelle. Es löscht eigentlich nichts und behebt leider das Problem, zuerst Einschränkungen zu löschen. Schade, ich hatte auf eine solche Antwort gehofft, ohne die Verwendung von sp_MSForEachTable (was für mich nicht existiert, Azure SQL Server)!
Pac0

Ja. wahr. Es erstellt ein abgeschnittenes Skript für alle Tabellen. Verwenden Sie dieses Skript, um Tabellendaten zu löschen.
Buddhika De Silva

Diese Lösung funktioniert nur, wenn keine Beziehungen bestehen, da nicht garantiert werden kann, dass die Tabellen in der richtigen Reihenfolge gelöscht werden. Wenn beim Löschen von Daten Auslöser auftreten, kann dies unbeabsichtigte Folgen haben.
dmoore1181
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.