231 Stimmen

Wie kann man mit TSQL alle Tabellen in einer Datenbank abschneiden?

Ich habe eine Testumgebung für eine Datenbank, die ich zu Beginn eines Testzyklus mit neuen Daten neu laden möchte. Ich möchte nicht die gesamte Datenbank neu aufbauen, sondern nur die Daten "neu einstellen".

Was ist der beste Weg, um alle Daten aus allen Tabellen mit TSQL zu entfernen? Gibt es gespeicherte Systemprozeduren, Ansichten usw., die verwendet werden können? Ich möchte nicht für jede Tabelle manuell eine Anweisung zum Abschneiden von Tabellen erstellen und pflegen - ich würde es vorziehen, wenn es dynamisch wäre.

457voto

kristof Punkte 50991

Wenn es darum geht, Daten aus Tabellen zu löschen, die Fremdschlüsselbeziehungen haben - was im Grunde bei jeder richtig konzipierten Datenbank der Fall ist - können wir alle Beschränkungen deaktivieren, alle Daten löschen und dann die Beschränkungen wieder aktivieren

-- disable all constraints
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- delete data in all tables
EXEC sp_MSForEachTable "DELETE FROM ?"

-- enable all constraints
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

Mehr über die Deaktivierung von Beschränkungen und Auslösern ici

wenn einige der Tabellen Identitätsspalten haben, wollen wir sie vielleicht neu sortieren

EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"

Beachten Sie, dass sich das Verhalten von RESEED zwischen einer brandneuen Tabelle und einer Tabelle unterscheidet, in die zuvor Daten aus BOL :

DBCC CHECKIDENT ('tabellenname', RESEED, newReseedValue)

Der aktuelle Identitätswert wird auf den newReseedValue gesetzt. Wenn keine Zeilen Zeilen in die Tabelle eingefügt wurden, seit sie erstellt wurde, wird die erste eingefügte Zeile nach der Ausführung von DBCC CHECKIDENT newReseedValue als Identität verwenden. Andernfalls wird die nächste eingefügte Zeile newReseedValue + 1 verwendet. Wenn der Wert von newReseedValue kleiner ist als der Maximalwert in der Identitätsspalte, wird die Fehlermeldung 2627 erzeugt bei nachfolgenden Verweisen auf die Tabelle erzeugt.

Dank an Robert für den Hinweis auf die Tatsache, dass die Deaktivierung von Beschränkungen die Verwendung von truncate nicht zulässt; die Beschränkungen müssten gelöscht und dann neu erstellt werden

41 Stimmen

Das Deaktivieren von Beschränkungen erlaubt NICHT das Abschneiden von Tabellen, die von einer FOREIGN KEY-Beschränkung referenziert werden. Die FK-Beschränkung muss aufgehoben werden. Bitte antworten Sie mir, wenn ich falsch liege, aber ich habe keine Möglichkeit gefunden, das Fallenlassen zu vermeiden.

0 Stimmen

Danke Robert, du hast Recht. Vielen Dank für diesen Hinweis. Ich habe meine Antwort aktualisiert.

1 Stimmen

Nur ein Tippfehler: Das Schlüsselwort "Table" sollte in dieser Anweisung nicht vorkommen EXEC sp_MSForEachTable "DELETE FROM TABLE ?" Die korrekte Version sollte lauten: EXEC sp_MSForEachTable "DELETE FROM ?"

208voto

Gulzar Nazim Punkte 51098

Für SQL 2005,

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'

Ein paar weitere Links für 2000 y 2005/2008 ..

68 Stimmen

Tabellen mit Fremdschlüsseln können nicht abgeschnitten werden. Dies funktioniert also nur, wenn es keine Fremdschlüssel-Beschränkungen zwischen Tabellen gibt (oder diese deaktiviert wurden).

2 Stimmen

Zugestimmt..ich dachte, da er speziell nach dem Abschneiden von Tabellen gefragt hat, hat er das Problem mit Fremdschlüsseln bereits gelöst.

0 Stimmen

@gulzar - sozusagen - ich habe eine separate Frage zum Umgang mit den FKs gepostet, aber Ihre Antwort steht für sich allein.

72voto

Chris KL Punkte 4742

Hier ist der King Daddy unter den Skripten zur Löschung von Datenbanken. Es löscht alle Tabellen und setzt sie korrekt wieder ein:

SET QUOTED_IDENTIFIER ON;
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? NOCHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? DISABLE TRIGGER ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? CHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? ENABLE TRIGGER ALL' 
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON';

IF NOT EXISTS (
    SELECT
        *
    FROM
        SYS.IDENTITY_COLUMNS
        JOIN SYS.TABLES ON SYS.IDENTITY_COLUMNS.Object_ID = SYS.TABLES.Object_ID
    WHERE
        SYS.TABLES.Object_ID = OBJECT_ID('?') AND SYS.IDENTITY_COLUMNS.Last_Value IS NULL
)
AND OBJECTPROPERTY( OBJECT_ID('?'), 'TableHasIdentity' ) = 1

    DBCC CHECKIDENT ('?', RESEED, 0) WITH NO_INFOMSGS;

Viel Spaß, aber seien Sie vorsichtig!

2 Stimmen

Leider schlägt der obige Befehl fehl, wenn Sie berechnete Spalten haben, da sp_MSforeachtable anscheinend über SET QUOTED_IDENTITY OFF in seinem Körper ( lien ). UPDATE: Die Lösung besteht darin, "SET QUOTED_IDENTIFIERS on;" an den Anfang jeder Anweisung zu setzen, die diesen Fehler auslöst (wie erwähnt aquí )

2 Stimmen

Es scheint, dass meine Identitäten dadurch nicht wiederhergestellt wurden.

50voto

Captain Kenpachi Punkte 6718

Am einfachsten ist es, dies zu tun, indem man

  1. Öffnen Sie SQL Management Studio
  2. Navigieren Sie zu Ihrer Datenbank
  3. Klicken Sie mit der rechten Maustaste und wählen Sie Aufgaben->Skripte generieren (Bild 1)
  4. Wählen Sie auf dem Bildschirm "Objekte auswählen" die Option "Bestimmte Objekte auswählen" und markieren Sie "Tabellen" (Bild 2).
  5. Wählen Sie auf dem nächsten Bildschirm "Erweitert" und ändern Sie dann die Option "Skript DROP und CREATE" in "Skript DROP und CREATE" (Bild 3)
  6. Sie können das Skript in einem neuen Editorfenster oder in einer Datei speichern und bei Bedarf ausführen.

erhalten Sie ein Skript, das alle Ihre Tabellen löscht und neu erstellt, ohne dass Sie sich Gedanken über Debugging oder die Frage machen müssen, ob Sie alles aufgenommen haben. Dies ist zwar mehr als nur ein Truncate, aber die Ergebnisse sind die gleichen. Denken Sie nur daran, dass Ihre automatisch inkrementierenden Primärschlüssel bei 0 beginnen, im Gegensatz zu abgeschnittenen Tabellen, die sich den zuletzt zugewiesenen Wert merken. Sie können dies auch vom Code aus ausführen, wenn Sie keinen Zugriff auf das Management Studio in Ihrer PreProd- oder Produktionsumgebung haben.

1.

enter image description here

2.

enter image description here

3.

enter image description here

3 Stimmen

Vorsicht, wenn Sie dies für eine Datenbank mit einem sehr komplexen Schema verwenden. Ich habe es an einer Entwicklungskopie unserer Produktions-DB ausprobiert und es hat das Schema zerstört, was eine komplette Neuverteilung erforderte.

1 Stimmen

Sie müssen alle Dinge, die Sie bewahren wollen, schriftlich festhalten.

1 Stimmen

DataGrip verfügt ebenfalls über diese Funktion. Genau das, was ich brauchte.

13voto

marcj Punkte 924

Das Abschneiden aller Tabellen funktioniert nur, wenn Sie keine Fremdschlüsselbeziehungen zwischen Ihren Tabellen haben, da SQL Server das Abschneiden einer Tabelle mit einem Fremdschlüssel nicht zulässt.

Eine Alternative dazu ist es, die Tabellen mit Fremdschlüsseln zu ermitteln und zuerst aus diesen zu löschen, dann können Sie die Tabellen ohne Fremdschlüssel abschneiden.

Voir http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341 y http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957 für weitere Einzelheiten.

1 Stimmen

Gutes Argument. Daran habe ich nicht gedacht. Ich könnte in der Lage sein, alle Beschränkungen zuerst zu deaktivieren und dann wieder zu aktivieren, sobald die Daten entfernt wurden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X