Comment supprimer toutes les tables d'une base de données avec une seule requête SQL?

176

Je ne veux pas taper le nom de toutes les tables pour les supprimer toutes. Est-ce possible avec une seule requête?

Majid
la source
3
Quelques recherches rapides sur Google ont révélé ceci: stackoverflow.com/questions/11053116/…
JSK NS
-bien que (pour SQLServer) cela puisse être plus utile: stackoverflow.com/questions/536350
Avec les bons noms d'utilisateur, cela pourrait se produire automatiquement ( lien xkcd obligatoire ).
Minnow
11
Avez-vous des clés étrangères sur les tables de la base de données? Si tel est le cas, vous devez en tenir compte et les supprimer avant d'essayer de supprimer des tables.
Anthony Grist
Gardez à l'esprit que si vous avez des objets liés au schéma, vous ne pouvez pas supprimer la table.
Sean Lange

Réponses:

177

Utilisez la vue INFORMATION_SCHEMA.TABLES pour obtenir la liste des tables. Générez des scripts Drop dans l'instruction select et supprimez-le à l'aide de Dynamic SQL:

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) + '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

Version de Sys.Tables

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' Drop table ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + '; '
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U'

Exec sp_executesql @sql

Remarque: si vous en avez foreign Keysdéfini entre les tables, exécutez d'abord la requête ci-dessous pour désactiver tout ce qui est foreign keysprésent dans votre base de données.

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

Pour plus d'informations, cliquez ici .

P ரதீப்
la source
3
(pas mon vote négatif) ... je m'en tiens généralement aux [sys]vues de schéma si la portabilité à travers rdbms n'est pas requise. stackoverflow.com/a/3654313/251174
swasheck
1
@DoubleA - C'est très simple. Je construis d'abord des instructions Drop pour toutes les tables de ma base de données et je les stocke dans une variable. Pour vérifier cela, vous pouvez utiliser Print @sqlavant exec. Ensuite, sp_executesql
j'exécute les
2
Si vous utilisez Azure, sp_msforeachtable n'est pas disponible. J'ai trouvé cette douce pépite de @Aaron Bertrand pour supprimer toutes les contraintes FK. Fonctionne vraiment bien avec cette réponse. dba.stackexchange.com/questions/90033/…
trevorc
3
Si sp_msforeachtable n'est pas disponible, vous pouvez également exécuter la requête de suppression plusieurs fois, car les tables qui dépendent d'autres sont ensuite supprimées :)
Maarten Kieft
88

Si vous souhaitez utiliser une seule requête SQL pour supprimer toutes les tables, vous pouvez utiliser ceci:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

Il s'agit d'une procédure stockée cachée dans le serveur SQL et sera exécutée pour chaque table de la base de données à laquelle vous êtes connecté.

Remarque: vous devrez peut-être exécuter la requête plusieurs fois pour supprimer toutes les tables en raison de dépendances.

Remarque 2: pour éviter la première note, avant d'exécuter la requête, vérifiez d'abord s'il existe des relations de clés étrangères avec une table. S'il y en a, désactivez simplement la contrainte de clé étrangère en exécutant la requête ci-dessous:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
RageContreLaMachine
la source
1
Je l'ai essayé sur ma base de données Azure SQL et cela n'a pas fonctionné. Cependant, la réponse ci-dessus (par Prdp) a fonctionné.
Artemious
4
Pour la note latérale, je dois exécuter la première commande plusieurs fois avant de supprimer toutes les tables, mais cela fonctionne bien.
Alper
1
@Thatshowweroll c'est probablement à cause des dépendances des tables. Si une table en a d'autres qui en dépendent, elle ne peut pas être supprimée.
RageAgainstTheMachine
1
@RageAgainstTheMachine oui, il s'agit certainement de tables avec plusieurs dépendances croisées. Je veux informer les utilisateurs de l'exécuter plusieurs fois, les erreurs ne sont pas des problèmes. Exécutez la première commande 3 à 4 fois, puis la deuxième commande 1 fois et la nomenclature. Cela fonctionne comme du charme!
Alper
1
@KyleVassella oui, cela ne s'exécutera que sur la base de données dans laquelle vous avez ouvert votre console
RageAgainstTheMachine
39

Si vous ne voulez pas taper, vous pouvez créer les instructions avec ceci:

USE Databasename

SELECT  'DROP TABLE [' + name + '];'
FROM    sys.tables

Ensuite, copiez et collez dans une nouvelle fenêtre SSMS pour l'exécuter.

Dave.Gugg
la source
Le nom de la table doit être entouré de [], mais fonctionne parfaitement même sur Azure
Ondra
1
Nous pouvons QUOTENAMEégalement utiliser ce qui a l'air soigné. 'DROP TABLE ' + QUOTENAME(name) + ';'
P ரதீப்
13

Vous pouvez également utiliser le script suivant pour tout supprimer, y compris les éléments suivants:

  • procédures stockées non système
  • vues
  • les fonctions
  • contraintes de clé étrangère
  • contraintes de clé primaire
  • les tables

https://michaelreichenbach.de/how-to-drop-everything-in-a-mssql-database/

/* 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
Silthus
la source
9

Je ferais juste une petite modification à la réponse et à l'utilisation de @ NoDisplayName QUOTENAME()sur la TABLE_NAMEcolonne et j'inclurais également la TABLE_SCHEMAcolonne encerclant les tables ne sont pas dans le dboschéma.

DECLARE @sql nvarchar(max) = '';

SELECT @sql += 'DROP TABLE ' + QUOTENAME([TABLE_SCHEMA]) + '.' + QUOTENAME([TABLE_NAME]) + ';'
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE [TABLE_TYPE] = 'BASE TABLE';

EXEC SP_EXECUTESQL @sql;

Ou en utilisant des sysvues de schéma (selon le commentaire de @ swasheck):

DECLARE @sql nvarchar(max) = '';

SELECT @sql += 'DROP TABLE ' + QUOTENAME([S].[name]) + '.' + QUOTENAME([T].[name]) + ';'
FROM [sys].[tables] AS [T]
INNER JOIN [sys].[schemas] AS [S] ON ([T].[schema_id] = [S].[schema_id])
WHERE [T].[type] = 'U' AND [T].[is_ms_shipped] = 0;

EXEC SP_EXECUTESQL @sql;
AeroX
la source
4
Je m'en tiens généralement aux [sys]vues de schéma si la portabilité à travers rdbms n'est pas requise. stackoverflow.com/a/3654313/251174
swasheck
1
@swasheck Merci pour le lien qui était assez intéressant. J'ai mis à jour la réponse avec une solution utilisant des vues de schéma sys.
AeroX
Vous pouvez utiliser la fonction Schema_name () pour obtenir le nom du schéma au lieu de rejoindre msdn.microsoft.com/en-us/library/ms175068.aspx
P ரதீப்
@NoDisplayName Ce n'est pas parce que vous le pouvez , que vous devriez ... blogs.sqlsentry.com/aaronbertrand/…
Aaron Bertrand
@AaronBertrand - Ma mauvaise pensée que cela pourrait être un meilleur moyen. merci de l'avoir signalé.
P ரதீப்
9

Pour faire suite à la réponse de Dave.Gugg, ce serait le code dont quelqu'un aurait besoin pour obtenir toutes les lignes DROP TABLE dans MySQL:

SELECT CONCAT('DROP TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = 'your_database_name'
OMA
la source
2
Je sais que l'affiche originale a étiqueté la question avec "sql-server", mais cela pourrait être utile à quelqu'un qui cherche à faire cela dans MySQL. En fait, j'ai trouvé cette question en cherchant une solution MySQL à cette question, donc je partage maintenant la solution que j'ai trouvée après avoir lu l'une des réponses ici.
OMA
7

Le moyen le plus simple est de supprimer toute la base de données et de la créer à nouveau:

drop database db_name
create database db_name

C'est tout.

Surveillance
la source
1
:) au moins pour moi, le but de supprimer toutes les tables est parce que la base de données ne peut pas être supprimée
Hasan Zafari
5
n'exécutez pas cette commande sur la base de données de l'entreprise. Ou soyez prêt à trouver un autre emploi.
Faraz
@FarazDurrani homme facile, abandonner toutes les tables ne semble pas non plus être un accord pour PROD db.
Supervision
5

Si quelqu'un d'autre a eu un problème avec la meilleure solution de réponse (y compris la désactivation des clés étrangères), voici une autre solution de ma part :

-- CLEAN DB
USE [DB_NAME]
    EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
    EXEC sp_MSForEachTable 'DELETE FROM ?'

    DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR
    SET @Cursor = CURSOR FAST_FORWARD FOR

    SELECT DISTINCT sql = 'ALTER TABLE [' + 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

    EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
Ani
la source
3

Pas tout à fait une requête, encore assez courte et douce:

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

Utilisez le script suivant pour droptous constraints:

DECLARE @sql NVARCHAR(max)=''

SELECT @sql += ' ALTER TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) +    ' NOCHECK CONSTRAINT all; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

Ensuite, exécutez ce qui suit pour supprimer toutes les tables:

select @sql='';

SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) + '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql

Cela a fonctionné pour moi dans Azure SQL Database où 'sp_msforeachtable'n'était pas disponible!

David Nyaoso
la source
1

Je sais que cette question est très ancienne mais chaque fois que j'ai besoin de ce code .. au fait, si vous avez des tables et des vues et des fonctions et des procédures, vous pouvez tout supprimer par ce script .. alors pourquoi je poste ce script ?? parce que si vous supprimez toutes les tables, vous devrez supprimer toutes les vues et si vous avez des fonctions et des procédures, vous devez les supprimer aussi
j'espère que cela aidera quelqu'un

DECLARE @sql NVARCHAR(max)=''

 SELECT @sql += ' Drop table ' + QUOTENAME(TABLE_SCHEMA) + '.'+ QUOTENAME(TABLE_NAME) 
+ '; '
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_TYPE = 'BASE TABLE'

Exec Sp_executesql @sql


 DECLARE @sql VARCHAR(MAX) = ''
    , @crlf VARCHAR(2) = CHAR(13) + CHAR(10) ;

 SELECT @sql = @sql + 'DROP VIEW ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + 
 QUOTENAME(v.name) +';' + @crlf
 FROM   sys.views v

 PRINT @sql;
 EXEC(@sql);

 declare @procName varchar(500)
 declare cur cursor 

 for select [name] from sys.objects where type = 'p'
 open cur
 fetch next from cur into @procName
 while @@fetch_status = 0
 begin
  exec('drop procedure [' + @procName + ']')
fetch next from cur into @procName
 end
  close cur
  deallocate cur

  Declare @sql NVARCHAR(MAX) = N'';

    SELECT @sql = @sql + N' DROP FUNCTION ' 
               + QUOTENAME(SCHEMA_NAME(schema_id)) 
               + N'.' + QUOTENAME(name)
    FROM sys.objects
  WHERE type_desc LIKE '%FUNCTION%';

   Exec sp_executesql @sql
  GO
Aladein
la source