Wie lösche ich alle Tabellen in einer SQL Server-Datenbank?

195

Ich versuche, ein Skript zu schreiben, das eine SQL Server-Datenbank vollständig leert. Das habe ich bisher:

USE [dbname]
GO
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DELETE ?'

Wenn ich es im Management Studio ausführe, erhalte ich:

Befehl (e) erfolgreich abgeschlossen.

Aber wenn ich die Tabellenliste aktualisiere, sind sie alle noch da. Was mache ich falsch?

Dixuji
quelle
Wenn keine der Lösungen auf dieser Seite funktioniert, haben Sie vielleicht vergessen: USE [DatabaseName] GO
Serj Sagan
2
LÖSCHEN? löscht die Datensätze aus der Tabelle. Sie sollten DROP TABLE? Verwenden, dies funktioniert jedoch aus anderen Gründen nicht.
Datum

Antworten:

305

Es funktioniert auch bei mir nicht, wenn mehrere Fremdschlüsseltabellen vorhanden sind.
Ich habe den Code gefunden, der funktioniert und alles tut, was Sie versuchen (alle Tabellen aus Ihrer Datenbank löschen):

DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR

SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.TABLE_SCHEMA + '].[' +  tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + '];'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME =rc1.CONSTRAINT_NAME

OPEN @Cursor FETCH NEXT FROM @Cursor INTO @Sql

WHILE (@@FETCH_STATUS = 0)
BEGIN
Exec sp_executesql @Sql
FETCH NEXT FROM @Cursor INTO @Sql
END

CLOSE @Cursor DEALLOCATE @Cursor
GO

EXEC sp_MSforeachtable 'DROP TABLE ?'
GO

Den Beitrag finden Sie hier . Es ist der Beitrag von Groker.

Gabriel GM
quelle
Warum ist es so, wenn Sie versuchen, den gesamten Codeblock mit einem BEGIN-END-Block in eine IF-Anweisung zu packen, die sich über den Cursor beschwert?
Adam
11
Ich Could not find stored procedure 'sp_MSForEachTable'.
erhalte
2
Diese Antwort funktioniert nicht, wenn Sie Tabellen (mit Einschränkungen) in einem anderen Schema als haben dbo. Wenn Sie benutzerdefinierte Schemata haben, müssen Sie Folgendes ändern sql:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg
5
sp_MSforeachtableist in Azure nicht verfügbar. Verwenden Sie stattdessen die Antwort von @ CountZero.
Ogglas
3
Diese Referenz wurde im Web gefunden (nicht in meiner): Eine Kopie der gespeicherten sp_MSforeachtable-Prozedur für Azure verwendet sp_MSforeach_worker: gist.github.com/metaskills/893599 .
João Vieira
329

Sie können alle Tabellen auch nur mit MSSMS-UI-Tools aus der Datenbank löschen (ohne SQL-Skript). Manchmal kann dieser Weg bequemer sein (besonders wenn er gelegentlich durchgeführt wird)

Ich mache das Schritt für Schritt wie folgt:

  1. Wählen Sie im Datenbankbaum 'Tabellen' (Objekt-Explorer).
  2. Drücken Sie F7, um die Detailansicht des Objekt-Explorers zu öffnen
  3. Wählen Sie in dieser Ansicht Tabellen aus, die gelöscht werden müssen (in diesem Fall alle)
  4. Drücken Sie die Entf-Taste, bis alle Tabellen gelöscht wurden (Sie wiederholen sie so oft wie Fehler aufgrund wichtiger Einschränkungen / Abhängigkeiten).
Bronek
quelle
5
Ich konnte sp_msforeachtable nicht dazu bringen, an einer Azure-SQL-Datenbank zu arbeiten. Ich vermute, sie enthalten es nicht für Azure. Diese Lösung funktioniert hervorragend und ist perfekt, wenn Sie sich über EF-Migrationen lustig machen oder viele Änderungen vornehmen (von vorne beginnen).
Trevorc
Berücksichtigt keine FKs / Bestellung.
Josh
1
Dies ist eine praktische Methode, wenn Sie sie nur hier und da ausführen müssen. Das Skript ist möglicherweise besser, wenn Sie es häufig ausführen.
Dylan Hayes
2
@Josh, die Reihenfolge wird nicht berücksichtigt. Wenn Sie jedoch im Dialogfeld "Löschen" auf "OK" klicken, werden weiterhin alle möglichen Tabellen gelöscht, wodurch schließlich alle Tabellen gelöscht werden.
ClayRay
Perfekte Lösung mit Designer
Zaheer
47

In SSMS:

  • Klicken Sie mit der rechten Maustaste auf die Datenbank
  • Gehen Sie zu "Aufgaben"
  • Klicken Sie auf "Skripte generieren".
  • Wählen Sie im Abschnitt "Objekte auswählen" die Option "Gesamte Datenbank und alle Datenbankobjekte skripten" aus.
  • Klicken Sie im Abschnitt "Skriptoptionen festlegen" auf die Schaltfläche "Erweitert"
  • Schalten Sie bei "Script DROP and CREATE" "Script CREATE" auf "Script DROP" und drücken Sie OK
  • Speichern Sie dann entweder in einer Datei, einer Zwischenablage oder einem neuen Abfragefenster.
  • Skript ausführen.

Dadurch wird nun alles gelöscht, einschließlich der Datenbank. Stellen Sie sicher, dass Sie den Code für die Elemente entfernen, die nicht gelöscht werden sollen. Alternativ können Sie im Abschnitt "Objekte auswählen" anstelle der Auswahl zum Skripten der gesamten Datenbank nur die Elemente auswählen, die Sie entfernen möchten.

Ben
quelle
3
Wenn Sie die Datenbank nicht löschen möchten (was in meinem Fall nicht der Fall ist, da ich dann einen Supportanruf tätigen müsste, um sie zu erstellen), verwenden Sie "Bestimmte Datenbankobjekte auswählen" und wählen Sie alle Objekttypen aus, die dies tun du willst fallen lassen.
d219
3
Dies ist der einfachste Weg.
Asiri Dissanayaka
2
Dies sollte auf jeden Fall die Antwort sein!
Zac Taylor
34

deletewird zum Löschen von Zeilen aus einer Tabelle verwendet. Sie sollten drop tablestattdessen verwenden.

EXEC sp_msforeachtable 'drop table [?]'
DaveShaw
quelle
Das schien das Problem behoben zu haben, keine Fehler zu haben, aber jetzt stoße ich auf Einschränkungsfehler. Ist die Syntax meiner NOCHECK CONSTRAINTZeile falsch?
Dixuji
1
Ich habe dies an zwei schnellen Tischen mit FKs verwendet und es hat funktioniert. EXEC sp_msforeachtable 'ALTER TABLE? NOCHECK CONSTRAINT all '
DaveShaw
12
Dies funktionierte nur für mich, nachdem ich die eckigen Klammern entfernt hatte: EXEC sp_msforeachtable 'drop table?'.
LPains
Unter SQL Server benötigen Sie die Klammern, wenn ein Tabellenname ungerade Zeichen oder Leerzeichen enthält. Ich kenne keine Version von SQL Server, die keine Klammern um Objektnamen unterstützt.
DaveShaw
Unter SQL Server 2012 (11.x) musste ich auch die eckigen Klammern entfernen.
Frieder
30

Die akzeptierte Antwort unterstützt Azure nicht. Es wird eine undokumentierte gespeicherte Prozedur "sp_MSforeachtable" verwendet. Wenn Sie beim Ausführen den Fehler "azure konnte die gespeicherte Prozedur 'sp_msforeachtable' nicht finden" erhalten oder einfach vermeiden möchten, sich auf undokumentierte Funktionen zu verlassen (die jederzeit entfernt oder deren Funktionalität geändert werden kann), versuchen Sie Folgendes.

Diese Version ignoriert die Entity Framework-Migrationsverlaufstabelle "__MigrationHistory" und die "database_firewall_rules", eine Azure-Tabelle, zu deren Löschung Sie nicht berechtigt sind.

Leicht auf Azure getestet. Stellen Sie sicher, dass dies keine unerwünschten Auswirkungen auf Ihre Umgebung hat.

DECLARE @sql NVARCHAR(2000)

WHILE(EXISTS(SELECT 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY'))
BEGIN
    SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
    EXEC(@sql)
    PRINT @sql
END

WHILE(EXISTS(SELECT * from INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'))
BEGIN
    SELECT TOP 1 @sql=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']')
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'
    EXEC(@sql)
    PRINT @sql
END

Genommen von:

https://edspencer.me.uk/2013/02/25/drop-all-tables-in-a-sql-server-database-azure-friendly/

http://www.sqlservercentral.com/blogs/sqlservertips/2011/10/11/remove-all-foreign-keys/

CountZero
quelle
3
Arbeitete als Magie auf Azurblau. Viel schneller als das Entfernen über die Benutzeroberfläche von VS
Simeon Grigorovich
27
/* 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
Harpal
quelle
1
Funktioniert in SQL Azure :) sp_MSforeachtable funktioniert dort nicht
Pavel Biryukov
Als Hinweis, dies wird fehlschlagen, wenn Sie Nicht-Dbo-Schemata haben (z. B. wenn Sie Hangfire verwenden)
Liam Dawson
21

Sie haben fast Recht, verwenden Sie stattdessen:

EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DROP TABLE ?'

In der zweiten Zeile müssen Sie möglicherweise mehr als einmal ausführen, bis kein Fehler mehr angezeigt wird:

Could not drop object 'dbo.table' because it is referenced by a FOREIGN KEY constraint.

Botschaft:

Command(s) completed successfully.

bedeutet, dass alle Tabellen erfolgreich gelöscht wurden.

Michał Powaga
quelle
17

Kurz und bündig:

USE YOUR_DATABASE_NAME
-- Disable all referential integrity constraints
EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO

-- Drop all PKs and FKs
declare @sql nvarchar(max)
SELECT @sql = STUFF((SELECT '; ' + 'ALTER TABLE ' + Table_Name  +'  drop constraint ' + Constraint_Name  from Information_Schema.CONSTRAINT_TABLE_USAGE ORDER BY Constraint_Name FOR XML PATH('')),1,1,'')
EXECUTE (@sql)
GO

-- Drop all tables
EXEC sp_MSforeachtable 'DROP TABLE ?'
GO
xx1xx
quelle
2
Ich hatte zu ersetzen sp_msforeachtabledurch sp_MSforeachtableund würde empfehlen , ein hinzufügen use yourdatabaseals erste Zeile. Lief wie am Schnürchen.
Simon Sobisch
Kurz und bündig! Danke.
Sapatelbaps
7

Der schnellste Weg ist:

  1. Neue Datenbankdiagramme
  2. Alle Tabelle hinzufügen
  3. Strg + A, um alle auszuwählen
  4. Klicken Sie mit der rechten Maustaste auf "Aus Datenbank entfernen".
  5. Strg + S zum Speichern
  6. Genießen
TuanDPH
quelle
Dies ist bei weitem der schnellste und weniger fehleranfällige Weg, dies zu tun. Dies sollte die akzeptierte Antwort sein.
DARKGuy
6

Scheint, der Befehl sollte ohne die quadratische Decke sein

EXEC sp_msforeachtable 'drop table ?'
Jimmy Wong
quelle
6

Für mich der einfachste Weg:

--First delete all constraints

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + N'
ALTER TABLE ' + QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + N' DROP CONSTRAINT '
+ QUOTENAME(c.name) + ';'
FROM sys.objects AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
INNER JOIN sys.schemas AS s 
ON t.[schema_id] = s.[schema_id]
WHERE c.[type] IN ('D','C','F','PK','UQ')
ORDER BY c.[type];

EXEC sys.sp_executesql @sql;

-- Then drop all tables

exec sp_MSforeachtable 'DROP TABLE ?'
Jeffrey
quelle
2

Genau richtig !!

Mit der folgenden Abfrage können Sie alle Tabellen aus der Datenbank entfernen

EXEC sp_MSforeachtable @ command1 = "DROP TABLE?"

Viel Spaß beim Codieren!

Gajanan Kulkarni
quelle
1

Wie wäre es, die gesamte Datenbank zu löschen und dann erneut zu erstellen? Das funktioniert bei mir.

DROP DATABASE mydb;
CREATE DATABASE mydb;
Chong Lip Phang
quelle
Müssen Sie die mdf- und ldf-Dateien nicht zwischendurch sprengen?
Ruffin
Ich benutze einen Webhost-Anbieter und bin mir da nicht sicher. Ich denke, diese Dateien werden automatisch gelöscht, wenn Sie eine Datenbank löschen, es sei denn, Sie sind offline.
Chong Lip Phang
2
Es hängt wirklich von den Umständen ab. In meinem Fall habe ich keine gespeicherten Prozeduren und diese Methode funktioniert gut für mich. Ich werde keine komplexen Codes schreiben, die Dutzende von Zeilen umfassen, wenn zwei Zeilen ausreichen. Ich glaube nicht, dass meine Antwort eine Ablehnung rechtfertigt, da ich einer bestimmten Gruppe von Benutzern einen Vorschlag mache.
Chong Lip Phang
0

Ich weiß, dass dies jetzt ein alter Beitrag ist, aber ich habe alle Antworten hier in einer Vielzahl von Datenbanken ausprobiert und festgestellt, dass sie alle manchmal, aber nicht immer für verschiedene (ich kann nur annehmen) Macken von SQL Server funktionieren.

Irgendwann habe ich mir das ausgedacht. Ich habe dies überall getestet (im Allgemeinen), was ich kann, und es funktioniert (ohne versteckte Speicherprozeduren).

Hinweis hauptsächlich auf SQL Server 2014. (aber die meisten anderen Versionen, die ich ausprobiert habe, scheinen auch gut zu funktionieren).

Ich habe versucht, während Schleifen und Nullen usw. usw., Cursor und verschiedene andere Formen, aber sie scheinen immer auf einigen Datenbanken zu scheitern, aber nicht auf anderen ohne offensichtlichen Grund.

Eine Zählung zu erhalten und diese zum Iterieren zu verwenden, scheint immer bei allem zu funktionieren, was ich getestet habe.

USE [****YOUR_DATABASE****]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- Drop all referential integrity constraints --
-- Drop all Primary Key constraints.          --

DECLARE @sql  NVARCHAR(296)
DECLARE @table_name VARCHAR(128)

DECLARE @constraint_name VARCHAR(128)
SET @constraint_name = ''

DECLARE @row_number INT

SELECT @row_number = Count(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME

WHILE @row_number > 0
BEGIN
    BEGIN
        SELECT TOP 1 @table_name = tc2.TABLE_NAME, @constraint_name = rc1.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
        LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME
        AND rc1.CONSTRAINT_NAME > @constraint_name
        ORDER BY rc1.CONSTRAINT_NAME
        SELECT @sql = 'ALTER TABLE [dbo].[' + RTRIM(@table_name) +'] DROP CONSTRAINT [' + RTRIM(@constraint_name)+']'
        EXEC (@sql)
        PRINT 'Dropped Constraint: ' + @constraint_name + ' on ' + @table_name
        SET @row_number = @row_number - 1
    END
END
GO

-- Drop all tables --

DECLARE @sql  NVARCHAR(156)
DECLARE @name VARCHAR(128)
SET @name = ''

DECLARE @row_number INT

SELECT @row_number = Count(*) FROM sysobjects WHERE [type] = 'U' AND category = 0

WHILE @row_number > 0
BEGIN
    SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name])
    SELECT @sql = 'DROP TABLE [dbo].[' + RTRIM(@name) +']'
    EXEC (@sql)
    PRINT 'Dropped Table: ' + @name
    SET @row_number = @row_number - 1
END
GO
William Humphreys
quelle
0

Für temporäre Tabellen ist es etwas komplizierter, da es möglicherweise einige Fremdschlüssel gibt und auch eine Ausnahme:

Drop table operation failed on table XXX because it is not a supported operation on system-versioned temporal tables

Was Sie verwenden können, ist:

-- Disable constraints (foreign keys)
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO

-- Disable system versioning (temporial tables)
EXEC sp_MSForEachTable '
 IF OBJECTPROPERTY(object_id(''?''), ''TableTemporalType'') = 2
  ALTER TABLE ? SET (SYSTEM_VERSIONING = OFF)
'
GO

-- Removing tables
EXEC sp_MSForEachTable 'DROP TABLE ?'
GO
J. Princewicz
quelle