Comment supprimer toutes les tables d'une base de données SQL Server?

196

J'essaie d'écrire un script qui videra complètement une base de données SQL Server. Voici ce que j'ai jusqu'à présent:

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

Lorsque je l'exécute dans Management Studio, j'obtiens:

Commande (s) terminée avec succès.

mais quand je rafraîchis la liste des tableaux, ils sont toujours là. Qu'est-ce que je fais mal?

dixuji
la source
Si aucune des solutions de cette page ne fonctionne, vous avez peut-être oublié de: USE [DatabaseName] GO
Serj Sagan
2
SUPPRIMER ? supprimera les enregistrements de la table. Vous devriez utiliser DROP TABLE?, Mais cela ne fonctionnera pas pour d'autres raisons.
datagod

Réponses:

306

Cela ne fonctionne pas non plus pour moi quand il y a plusieurs tables de clés étrangères.
J'ai trouvé ce code qui fonctionne et fait tout ce que vous essayez (supprimez toutes les tables de votre base de données):

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

Vous pouvez trouver le message ici . C'est le message de Groker.

Gabriel GM
la source
Pourquoi est-ce que lorsque vous essayez d'encapsuler tout ce bloc de code dans une instruction IF en utilisant un bloc BEGIN-END, il se plaint du curseur?
Adam
11
Je reçois une erreurCould not find stored procedure 'sp_MSForEachTable'.
Korayem
2
Cette réponse ne fonctionne pas si vous avez des tables (avec des contraintes) dans un schéma différent de dbo. Si vous avez des schémas personnalisés, vous devez modifier le sqlà:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg
5
sp_MSforeachtablen'est pas disponible dans Azure. Utilisez plutôt la réponse de @ CountZero.
Ogglas
3
J'ai trouvé cette référence sur le Web (pas la mienne): Une copie de la procédure stockée sp_MSforeachtable pour Azure, utilise sp_MSforeach_worker: gist.github.com/metaskills/893599 .
João Vieira
333

Vous pouvez également supprimer toutes les tables de la base de données en utilisant uniquement les outils d'interface utilisateur MSSMS (sans utiliser de script SQL). Parfois, cette méthode peut être plus confortable (surtout si elle est effectuée occasionnellement)

Je fais cela étape par étape comme suit:

  1. Sélectionnez 'Tables' dans l'arborescence de la base de données (Object Explorer)
  2. Appuyez sur F7 pour ouvrir la vue Détails de l'Explorateur d'objets
  3. Dans cette vue, sélectionnez les tables qui doivent être supprimées (dans ce cas, toutes)
  4. Continuez à appuyer sur Supprimer jusqu'à ce que toutes les tables aient été supprimées (vous le répétez autant de fois que le nombre d'erreurs dues à des contraintes / dépendances clés)
Bronek
la source
5
Je n'ai pas pu faire fonctionner sp_msforeachtable sur une base de données Azure SQL. Je suppose qu'ils ne l'incluent pas pour Azure. Cette solution fonctionne très bien et est parfaite pour se moquer ou apporter de nombreuses modifications (recommencer) avec les migrations EF.
trevorc
Ne tient pas compte des FK / commande.
Josh
1
c'est une méthode pratique si vous avez juste besoin de le faire ici et là, le script peut être mieux si vous le faites souvent.
Dylan Hayes
2
@Josh, l'ordre n'est pas pris en compte mais si vous continuez d'appuyer sur Ok dans la boîte de dialogue Supprimer, il continuera à supprimer toutes les tables possibles, ce qui finira par supprimer toutes les tables.
clayRay
Solution parfaite utilisant Designer
Zaheer
50

Dans SSMS:

  • Faites un clic droit sur la base de données
  • Allez dans "Tâches"
  • Cliquez sur "Générer des scripts"
  • Dans la section "Choisir les objets", sélectionnez "Script toute la base de données et tous les objets de la base de données"
  • Dans la section "Définir les options de script", cliquez sur le bouton "Avancé"
  • Sur "Script DROP and CREATE", basculez "Script CREATE" sur "Script DROP" et appuyez sur OK
  • Ensuite, enregistrez-le dans un fichier, dans le presse-papiers ou dans une nouvelle fenêtre de requête.
  • Script de lancement.

Maintenant, cela supprimera tout, y compris la base de données. Assurez-vous de supprimer le code des éléments que vous ne souhaitez pas supprimer. Sinon, dans la section "Choisir des objets", au lieu de sélectionner pour script toute la base de données, sélectionnez simplement les éléments que vous souhaitez supprimer.

Ben
la source
4
Si vous ne voulez pas supprimer la base de données (ce qui dans mon cas, je ne le fais pas, car je devrais alors faire un appel au support pour la créer), utilisez `` Sélectionner des objets de base de données spécifiques '' et sélectionnez tous les types d'objets qui vous souhaitez abandonner.
d219
4
C'est le moyen le plus simple.
Asiri Dissanayaka
3
Cela devrait être la réponse à coup sûr!
Zac Taylor
34

deleteest utilisé pour supprimer des lignes d'une table. Vous devriez utiliser à la drop tableplace.

EXEC sp_msforeachtable 'drop table [?]'
DaveShaw
la source
Cela semblait avoir résolu le problème de ne pas avoir d'erreur, mais maintenant je rencontre des erreurs de contrainte. La syntaxe de ma NOCHECK CONSTRAINTligne est-elle incorrecte?
dixuji
1
Je l'ai utilisé sur deux tables rapides avec FK et cela a fonctionné. EXEC sp_msforeachtable 'ALTER TABLE? NOCHECK CONSTRAINT all '
DaveShaw
12
Cela n'a fonctionné pour moi qu'après avoir supprimé les crochets: EXEC sp_msforeachtable 'drop table?'.
LPains du
Sur SQL Server, vous avez besoin des crochets si un nom de table contient des caractères ou des espaces impairs. Je ne connais pas de version de SQL Server qui ne prenait pas en charge les crochets autour des noms d'objets.
DaveShaw
Sur SQL Server 2012 (11.x), j'ai également dû supprimer les crochets.
Frieder le
30

La réponse acceptée ne prend pas en charge Azure. Il utilise une procédure stockée non documentée "sp_MSforeachtable". Si vous obtenez une erreur "azure n'a pas pu trouver la procédure stockée 'sp_msforeachtable" lors de l'exécution ou si vous voulez simplement éviter de vous fier à des fonctionnalités non documentées (qui peuvent être supprimées ou avoir leurs fonctionnalités modifiées à tout moment), essayez ce qui suit.

Cette version ignore la table d'historique de migration du framework d'entités «__MigrationHistory» et «database_firewall_rules», qui est une table Azure que vous ne serez pas autorisé à supprimer.

Légèrement testé sur Azure. Vérifiez que cela n'a aucun effet indésirable sur votre environnement.

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

Pris à partir de:

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
la source
3
A travaillé comme magie sur azur. Beaucoup plus rapide que la suppression via l'interface utilisateur de 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
la source
1
Fonctionne dans SQL Azure :) sp_MSforeachtable ne fonctionne pas là
Pavel Biryukov
À noter, cela échouera si vous avez des schémas non-dbo (par exemple si vous utilisez Hangfire)
Liam Dawson
21

Vous avez presque raison, utilisez à la place:

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

mais la deuxième ligne, vous devrez peut-être exécuter plus d'une fois jusqu'à ce que vous cessiez d'obtenir l'erreur:

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

Message:

Command(s) completed successfully.

signifie que toutes les tables ont été supprimées avec succès.

Michał Powaga
la source
17

Court et doux:

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
la source
2
J'ai dû remplacer sp_msforeachtablepar sp_MSforeachtableet je recommande vivement d'ajouter un use yourdatabasecomme première ligne. A travaillé comme un charme.
Simon Sobisch
Court et doux! Thnx.
sapatelbaps
7

La voie à jeun est:

  1. Nouveaux diagrammes de base de données
  2. Ajouter tout le tableau
  3. Ctrl + A pour tout sélectionner
  4. Cliquez avec le bouton droit sur "Supprimer de la base de données"
  5. Ctrl + S pour enregistrer
  6. Prendre plaisir
TuanDPH
la source
C'est de loin le moyen le plus rapide et le moins sujet aux erreurs. Cela devrait être la réponse acceptée.
DARKGuy
6

Il semble que la commande devrait être sans la couverture carrée

EXEC sp_msforeachtable 'drop table ?'
Jimmy Wong
la source
6

Pour moi, le moyen le plus simple:

--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
la source
2

Spot on !!

Vous pouvez utiliser la requête ci-dessous pour supprimer toutes les tables de la base de données

EXEC sp_MSforeachtable @ command1 = "DROP TABLE?"

Bon codage!

Gajanan Kulkarni
la source
1

Que diriez-vous de supprimer toute la base de données et de la créer à nouveau? Cela fonctionne pour moi.

DROP DATABASE mydb;
CREATE DATABASE mydb;
Chong Lip Phang
la source
Vous n'avez pas besoin de faire sauter les fichiers mdf et ldf entre les deux?
ruffin
J'utilise un fournisseur d'hébergement Web et je n'en suis pas trop sûr. Je pense que ces fichiers seront supprimés automatiquement lorsque vous supprimez une base de données, sauf si vous êtes hors ligne.
Chong Lip Phang
2
Cela dépend vraiment des circonstances. Dans mon cas, je n'ai pas de procédures stockées et cette méthode fonctionne très bien pour moi. Je ne vais pas écrire des codes complexes qui s'étendent sur des dizaines de lignes alors que deux lignes suffiront. Je ne pense pas que ma réponse justifie un vote négatif car j'offre une suggestion à un groupe spécifique d'utilisateurs.
Chong Lip Phang
0

Je sais que c'est un ancien message maintenant, mais j'ai essayé toutes les réponses ici sur une multitude de bases de données et j'ai trouvé qu'elles fonctionnent toutes parfois mais pas tout le temps pour diverses bizarreries (je ne peux que supposer) de SQL Server.

Finalement, je suis venu avec ça. J'ai testé cela partout (en général) je peux et cela fonctionne (sans aucune procédure de magasin caché).

À noter principalement sur SQL Server 2014. (mais la plupart des autres versions que j'ai essayées semblent également fonctionner correctement).

J'ai essayé des boucles while et des valeurs nulles, etc., des curseurs et diverses autres formes, mais ils semblent toujours échouer sur certaines bases de données mais pas sur d'autres sans raison évidente.

Obtenir un décompte et l'utiliser pour itérer semble toujours fonctionner sur tout ce que j'ai testé.

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
la source
0

Pour les tables temporelles, c'est un peu plus compliqué en raison du fait qu'il peut y avoir des clés étrangères et aussi des exceptions:

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

Ce que vous pouvez utiliser est:

-- 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.Wincewicz
la source