Jak usunąć wszystkie tabele z bazy danych za pomocą jednego zapytania SQL?

176

Nie chcę wpisywać nazw wszystkich tabel, aby je wszystkie usunąć. Czy jest to możliwe za pomocą jednego zapytania?

Majid
źródło
3
Ujawniło to trochę googlowania: stackoverflow.com/questions/11053116/ ...
JSK NS
- chociaż (dla SQLServer) może to być bardziej przydatne: stackoverflow.com/questions/536350/ ...
Przy prawidłowych nazwach użytkowników może to nastąpić automatycznie ( obowiązkowy link xkcd ).
Minnow
11
Czy masz jakieś klucze obce w tabelach w bazie danych? Jeśli tak, musisz wziąć to pod uwagę i porzucić je przed próbą usunięcia tabel.
Anthony Grist
Pamiętaj, że jeśli masz obiekty otoczone schematem, nie możesz upuścić tabeli.
Sean Lange

Odpowiedzi:

176

Aby uzyskać listę tabel, użyj widoku INFORMATION_SCHEMA.TABLES . Wygeneruj skrypty upuszczania w instrukcji select i upuść je za pomocą 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

Sys.Tables Version

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

Uwaga: Jeśli masz foreign Keyszdefiniowane między tabelami, najpierw uruchom poniższe zapytanie, aby wyłączyć wszystkie foreign keysobecne w bazie danych.

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

Więcej informacji znajdziesz tutaj .

P ரதீப்
źródło
3
(nie moja negatywna opinia) ... generalnie trzymałbym się [sys]widoków schematu, jeśli przenoszenie przez rdbms nie jest wymagane. stackoverflow.com/a/3654313/251174
swasheck
1
@DoubleA - To bardzo proste. Najpierw buduję instrukcje Drop dla wszystkich tabel w mojej bazie danych i przechowuję je w zmiennej. Aby to sprawdzić, możesz użyć Print @sqlwcześniej exec. Następnie sp_executesql
wykonuję
2
Jeśli korzystasz z platformy Azure, usługa sp_msforeachtable jest niedostępna. Znalazłem tę słodką bryłkę od @Aaron Bertrand, aby usunąć wszystkie ograniczenia FK. Działa naprawdę dobrze z tą odpowiedzią. dba.stackexchange.com/questions/90033/…
trevorc
3
Jeśli sp_msforeachtable nie jest dostępny, możesz również uruchomić zapytanie usuwające wiele razy, ponieważ tabele zależne od innych są następnie usuwane :)
Maarten Kieft
88

Jeśli chcesz użyć tylko jednego zapytania SQL do usunięcia wszystkich tabel, możesz użyć tego:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

Jest to ukryta procedura składowana na serwerze sql i zostanie wykonana dla każdej tabeli w bazie danych, z którą się łączysz.

Uwaga: może być konieczne wykonanie zapytania kilka razy, aby usunąć wszystkie tabele ze względu na zależności.

Uwaga 2 : Aby uniknąć pierwszej notatki, przed uruchomieniem zapytania najpierw sprawdź, czy istnieją relacje kluczy obcych z jakąkolwiek tabelą. Jeśli tak, po prostu wyłącz ograniczenie klucza obcego, uruchamiając zapytanie poniżej:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
RageAgainstTheMachine
źródło
1
Wypróbowałem to na mojej bazie danych Azure SQL i nie zadziałało. Jednak powyższa odpowiedź (autorstwa Prdp) zadziałała.
Artemious
4
Na marginesie, muszę wielokrotnie uruchamiać pierwsze polecenie, zanim porzuciłem wszystkie tabele, ale działa dobrze.
Alper
1
@Thatshowweroll jest to prawdopodobnie spowodowane zależnościami tabel. Jeśli jedna tabela ma inne, które są od niej zależne, nie można jej usunąć.
RageAgainstTheMachine
1
@RageAgainstTheMachine tak, zdecydowanie pochodzi z tabel z wieloma zależnościami krzyżowymi. Chcę poinformować użytkowników, aby uruchamiali go wiele razy, błędy to nie problemy. Uruchom pierwsze polecenie 3-4 razy, a następnie drugie polecenie 1 raz i zestawienie komponentów. Działa jak urok!
Alper
1
@KyleVassella tak, to wykona się tylko w bazie danych, w której masz otwartą konsolę
RageAgainstTheMachine
39

Jeśli nie chcesz pisać, możesz utworzyć instrukcje za pomocą tego:

USE Databasename

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

Następnie skopiuj i wklej do nowego okna SSMS, aby go uruchomić.

Dave.Gugg
źródło
nazwa tabeli powinna być zawarta w [], ale działa świetnie nawet na Azure
Ondra
1
Możemy użyć QUOTENAMErównież, która wygląda schludnie. 'DROP TABLE ' + QUOTENAME(name) + ';'
P ரதீப்
13

Możesz również użyć następującego skryptu, aby porzucić wszystko, w tym następujące:

  • niesystemowe procedury składowane
  • wyświetlenia
  • Funkcje
  • ograniczenia klucza obcego
  • ograniczenia klucza podstawowego
  • stoły

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
źródło
9

Po prostu wprowadziłbym małą zmianę w odpowiedzi @ NoDisplayName i użyłbym QUOTENAME()go w TABLE_NAMEkolumnie, a także dołączyłbym TABLE_SCHEMAkolumnę, aby tabele nie były w dboschemacie.

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;

Lub używając syswidoków schematu (zgodnie z komentarzem @ 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
źródło
4
Generalnie [sys]trzymałbym się widoków schematu, jeśli przenośność w Rdbms nie jest wymagana. stackoverflow.com/a/3654313/251174
swasheck
1
@swasheck Dzięki za dość interesujący link. Zaktualizowałem odpowiedź za pomocą rozwiązania wykorzystującego widoki schematu sys.
AeroX,
Możesz użyć funkcji Schema_name (), aby uzyskać nazwę schematu zamiast dołączać do msdn.microsoft.com/en-us/library/ms175068.aspx
P ரதீப்
@NoDisplayName Tylko dlatego, że możesz , nie oznacza, że powinieneś ... blogs.sqlsentry.com/aaronbertrand/
Aaron Bertrand
@AaronBertrand - Moja zła myśl, że może to być lepszy sposób. dzięki za wskazanie tego.
P ரதீப்
9

W następstwie odpowiedzi Dave.Gugga, byłby to kod, który ktoś potrzebowałby, aby pobrać wszystkie linie DROP TABLE w MySQL:

SELECT CONCAT('DROP TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = 'your_database_name'
OMA
źródło
2
Wiem, że na oryginalnym plakacie pytanie było oznaczone jako „sql-server”, ale może to być przydatne dla kogoś, kto chce to zrobić w MySQL. W rzeczywistości znalazłem to pytanie, szukając rozwiązania MySQL na to pytanie, więc teraz udostępniam rozwiązanie, które wymyśliłem po przeczytaniu jednej z odpowiedzi tutaj.
OMA
7

Najprostszym sposobem jest usunięcie całej bazy danych i utworzenie jej jeszcze raz:

drop database db_name
create database db_name

To wszystko.

Nadzór
źródło
1
:) przynajmniej dla mnie celem usunięcia wszystkich tabel jest to, że bazy danych nie można usunąć
Hasan Zafari
5
nie uruchamiaj tego polecenia w bazie danych firmy. Lub przygotuj się na znalezienie innej pracy.
Faraz
@FarazDurrani łatwy człowieku, porzucenie wszystkich tabel również nie wydaje się być transakcją dla PROD db.
Nadzór
5

Jeśli ktoś inny miał problem z rozwiązaniem najlepszej odpowiedzi (w tym z wyłączeniem kluczy obcych), oto inne rozwiązanie ode mnie :

-- 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
źródło
3

Niezupełnie 1 zapytanie, wciąż dość krótkie i słodkie:

-- 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
źródło
3

Użyj poniższego skryptu do dropwszystkich 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

Następnie wykonaj poniższe czynności, aby usunąć wszystkie tabele:

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

To zadziałało dla mnie w Azure SQL Database, gdzie 'sp_msforeachtable'nie było dostępne!

David Nyaoso
źródło
1

Wiem, że to pytanie jest bardzo stare, ale za każdym razem, gdy potrzebuję tego kodu ... tak przy okazji, jeśli masz tabele i widoki oraz Funkcje i PROCEDURY, możesz je usunąć za pomocą tego skryptu ... więc po co umieszczam ten skrypt? ponieważ jeśli usuniesz wszystkie tabele, będziesz musiał usunąć wszystkie widoki, a jeśli masz Funkcje i PROCEDURY, musisz je również usunąć.
Mam nadzieję, że to komuś pomoże

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
źródło