Supprimer toutes les données de la base de données SQL Server


Réponses:


194

La solution de SQLMenace a fonctionné pour moi avec une légère modification de la façon dont les données sont supprimées - DELETE FROMau lieu de 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 .. J'ai pu supprimer, mais pas tronquer.
Marcel

17
Il peut également être judicieux de faire un EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'après le DELETE FROM pour réinitialiser toutes les colonnes d'identité à 0.
Jonathan Amend

1
C'est toujours un bon début de journée lorsque vous trouvez 6 lignes de code qui remplacent des centaines d'instructions de suppression! Cette méthode fonctionne sans problème sur SQL 2014 Express.
Tommy

1
N'oubliez pas de désactiver les déclencheurs également
Edwin Stoteler

10
J'obtenais une erreur - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Pour moi travaillé:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Habituellement, je vais simplement utiliser le proc sp_MSForEachTable non documenté

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

Voir aussi: Supprimer toutes les données de la base de données (lorsque vous avez des FK)


1
Je ne pense pas que cela fonctionne. On dirait que Kalen Delaney a été responsable par inadvertance du lancement de cette idée. Ici, elle clarifie "vous devez supprimer la contrainte de référencement pour tronquer la table".
Martin Smith

Martin Je viens de l'exécuter il y a 2 secondes dans la base de données Adventureworks sans problème
SQLMenace

Cela ne fonctionne certainement pas pour moi ici. 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
Cela ne fonctionne pas, bien qu'il soit marqué comme la réponse. La définition de la contrainte nocheck sur les clés étrangères ne vous permet pas d'exécuter des commandes tronquées sur ces tables. Vous obtiendrez toujours des erreurs qui vous empêcheront de tronquer.
Quatrième

3
cela ne fonctionne pas en raison de la présence de clés étrangères. Je ne vois toujours pas pourquoi cela a été accepté comme réponse: /
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

script intéressant, qui n'utilise pas le proc stocké non codé 'sp_MSForEachTable', qui manque sur Azure. A besoin d'être peaufiné si vous avez des objets sur un autre schéma que [dbo], cependant.
Pac0

Veuillez utiliser gist.github.com/metaskills/893599 pour créer sp_MSForEachTable dans Azure
Harpal

16

Je sais que c'est tard, mais je suis d'accord avec la suggestion d'AlexKuznetsov de scripter la base de données, plutôt que de passer par les tracas de purger les données des tables. Si la TRUNCATEsolution ne fonctionne pas et que vous avez une grande quantité de données, l'émission d' DELETEinstructions (consignées) peut prendre du temps et vous vous retrouverez avec des identifiants qui n'ont pas été réensemencés (c'est-à-dire une INSERTinstruction dans une table avec une IDENTITYcolonne vous donnerait un ID de 50000 au lieu d'un ID de 1).

Pour créer un script pour une base de données entière, dans SSMS, cliquez avec le bouton droit sur la base de données, puis sélectionnez TASKS-> Generate scripts:

entrez la description de l'image ici

Cliquez Nextpour ignorer l'écran d'ouverture de l'assistant, puis sélectionnez les objets que vous souhaitez script:

entrez la description de l'image ici

Dans l' Set scripting optionsécran, vous pouvez choisir des paramètres pour le script, comme s'il faut générer 1 script pour tous les objets ou des scripts séparés pour les objets individuels, et s'il faut enregistrer le fichier au format Unicode ou ANSI:

entrez la description de l'image ici

L'assistant affiche un résumé, que vous pouvez utiliser pour vérifier que tout est comme vous le souhaitez, et se ferme en cliquant sur «Terminer».


Attention, de cette façon par défaut vous perdrez des trucs comme des index si vous n'allez pas sur le bouton "Avancé".
glautrou

6
  1. Vous devrez d'abord désactiver tous les déclencheurs:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Exécutez ce script: (Tiré de ce post Merci @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

Ce script produira des DELETEinstructions dans le bon ordre. à partir des tables référencées puis en référençant celles

  1. Copiez les DELETE FROMinstructions et exécutez-les une fois

  2. activer les déclencheurs

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Validez les modifications:

    begin transaction
    commit;

Cela ne fonctionne pas pour moi, la requête récursive se termine dans une boucle. Peut-être à cause du respect de soi.
Edwin Stoteler

5

Il est généralement beaucoup plus rapide d'exécuter un script de tous les objets de la base de données et d'en créer un vide, que de supprimer ou de tronquer les tables.


3

Ci-dessous un script que j'ai utilisé pour supprimer toutes les données d'une base de données 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

En guise de réponse alternative, si vous comparez Visual Studio SSDT ou éventuellement Red Gate Sql Compare, vous pouvez simplement exécuter une comparaison de schéma, l'écrire en script, supprimer l'ancienne base de données (éventuellement faire une sauvegarde en premier au cas où il y aurait une raison pour laquelle vous auriez besoin ces données), puis créez une nouvelle base de données avec le script créé par l'outil de comparaison. Alors que sur une très petite base de données cela peut être plus de travail, sur une très grande base de données, il sera beaucoup plus rapide de simplement supprimer la base de données puis de traiter les différents déclencheurs et contraintes qui peuvent être sur la base de données.


-1

Oui, il est possible de supprimer avec une seule ligne de code

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

Cela me donne une nouvelle table avec une instruction tronquée pour chaque table. Il ne supprime rien en fait et, malheureusement, il s'occupe d'abord du problème de la suppression des contraintes. Dommage, j'espérais une réponse comme ça, sans l'utilisation de sp_MSForEachTable (qui n'existe pas pour moi, Azure SQL Server)!
Pac0

Oui. vrai. son script create truncate pour toutes les tables. Utilisez ce script pour supprimer les données des tables.
Buddhika De Silva

Cette solution ne fonctionne que dans le cas où il n'y a pas de relations, car elle n'a aucun moyen de garantir que les tables sont supprimées dans le bon ordre. En outre, s'il y a des déclencheurs sur les suppressions de données, cela pourrait entraîner des conséquences inattendues.
dmoore1181
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.