Як видалити всі таблиці з бази даних за допомогою одного SQL-запиту?


176

Я не хочу вводити ім'я всіх таблиць, щоб відкинути їх усі. Чи можливо за допомогою одного запиту?


3
Деякі швидкі гуглінг виявили це: stackoverflow.com/questions/11053116/…
JSK NS

-Хоча (для SQLServer) це могло б бути більш корисним: stackoverflow.com/questions/536350 / ...

З правильними іменами користувачів це може статися автоматично ( обов'язкове посилання xkcd ).
Мінноув

11
Чи є у вас бази даних на таблицях в базі даних? Якщо так, то вам потрібно буде це врахувати та відкинути їх, перш ніж намагатися скинути таблиці.
Ентоні Грист

Майте на увазі, що якщо у вас є об'єкти, пов’язані із схемою, ви не можете опустити таблицю.
Шон Ланге

Відповіді:


176

Скористайтеся поданням INFORMATION_SCHEMA.TABLES, щоб отримати список таблиць. Створіть сценарії Drop в операторі select і опустіть його за допомогою 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

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

Примітка. Якщо у вас є якісь foreign Keysвизначення між таблицями, спочатку запустіть запит нижче, щоб відключити всі foreign keysприсутні у вашій базі даних.

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

Для отримання додаткової інформації перевірте тут .


3
(не мій downvote) ... я, як правило, дотримуюся представлень [sys]схеми, якщо переносимість через rdbms 'не потрібна. stackoverflow.com/a/3654313/251174
swasheck


1
@DoubleA - Це дуже просто. Спочатку будую оператори Drop для всіх таблиць моєї бази даних і зберігаю їх у змінній. Щоб перевірити це, ви можете використовувати Print @sqlраніше exec. Тоді я sp_executesql
виконую

2
Якщо ви використовуєте Azure, sp_msforeachtable недоступний. Я знайшов цей солодкий самородок від @Aaron Bertrand, щоб видалити всі обмеження FK. Діє дуже добре з цією відповіддю. dba.stackexchange.com/questions/90033/…
trevorc

3
Якщо sp_msforeachtable недоступний, ви також можете виконати запит на видалення кілька разів, оскільки таблиці, які залежать від інших, видаляються :)
Maarten

88

Якщо ви хочете використовувати лише один SQL-запит для видалення всіх таблиць, ви можете скористатися цим:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

Це прихована процедура зберігання на сервері sql та виконується для кожної таблиці в підключеній базі даних.

Примітка. Можливо, вам потрібно буде виконати запит кілька разів, щоб видалити всі таблиці через залежність.

Примітка2. Щоб уникнути першої примітки, перш ніж запустити запит, спочатку перевірте, чи є стосунки зовнішніх ключів до будь-якої таблиці. Якщо є, тоді просто відключіть обмеження на зовнішній ключ, запустивши запит нижче:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

1
Я спробував це в моїй базі даних SQL Azure, і це не спрацювало. Однак вищезазначена відповідь (Prdp) спрацювала.
Артемічний

4
Для бічної примітки мені потрібно запустити першу команду кілька разів, перш ніж скинути всі таблиці, але вона працює добре.
Альпер

1
@Thatshowweroll це, мабуть, через залежності таблиць. Якщо в одній таблиці є інші, які залежать від неї, її не можна видалити.
RageAgainstTheMachine

1
@RageAgainstTheMachine так, це безумовно з таблиць з декількома перехресними залежностями. Хочу повідомити користувачів, щоб це було запущено кілька разів, помилки - це не проблеми. Виконайте першу команду 3-4 рази, потім другу команду 1 раз та BOM. Це працює як шарм!
Альпер

1
@KyleVassella так, це буде виконано лише в базі даних, у якій ваша консоль відкрита
RageAgainstTheMachine

39

Якщо ви не хочете вводити, ви можете створити оператори з цим:

USE Databasename

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

Потім скопіюйте та вставте у нове вікно SSMS, щоб запустити його.


Ім'я таблиці має бути загорнене в [], але чудово працює навіть у Azure
Ondra

1
Ми можемо використовувати QUOTENAMEі те, що виглядає акуратно. 'DROP TABLE ' + QUOTENAME(name) + ';'
P ரதீப்

13

Ви також можете скористатися наступним сценарієм, щоб скинути все, включаючи таке:

  • несистемні збережені процедури
  • поглядів
  • функції
  • іноземні ключові обмеження
  • обмеження первинного ключа
  • столи

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

9

Я просто вніс невелику зміну у відповідь та використання @ NoDisplayName QUOTENAME()у TABLE_NAMEстовпці, а також включити TABLE_SCHEMAстовпчик, що містить шрифти, таблиць не в dboсхемі.

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схем (відповідно до коментаря @ 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;

4
Я б зазвичай дотримувався подання [sys]схеми, якщо не потрібна переносимість через rdbms. stackoverflow.com/a/3654313/251174
swasheck

1
@swasheck Дякую за цікаве посилання. Я оновив відповідь рішенням, використовуючи подання схеми sys.
AeroX

Ви можете скористатися функцією Schema_name (), щоб отримати ім'я схеми замість приєднання до msdn.microsoft.com/en-us/library/ms175068.aspx
P

@NoDisplayName Тільки тому, що ви можете , не означає, що вам слід ... blogs.sqlsentry.com/aaronbertrand/…
Аарон Бертран

@AaronBertrand - Моя погана думка, що це може бути кращий спосіб. дякую, що вказали на це.
P ரதீப்

9

Як відповідь на відповідь Dave.Gugg, це буде код, який комусь знадобиться, щоб отримати всі рядки DROP TABLE в MySQL:

SELECT CONCAT('DROP TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = 'your_database_name'

2
Я знаю, що в оригінальному плакаті було позначено питання "sql-сервером", але це може бути корисно тому, хто хоче це зробити в MySQL. Насправді я знайшов це питання, коли гуглював для вирішення цього питання на MySQL, тож зараз я ділюсь рішенням, яке я придумав, прочитавши одну з відповідей тут.
ОМА

7

Найпростіший спосіб - скинути всю базу даних і створити її ще раз:

drop database db_name
create database db_name

Це все.


1
:) принаймні для мене мета скидання всіх таблиць полягає в тому, що базу даних неможливо видалити
Hasan Zafari

5
не запускайте цю команду в базі даних компанії. Або будьте готові знайти іншу роботу.
Фараз

@FarazDurrani проста людина, опускання всіх таблиць теж не здається для PROD db.
Нагляд

5

Якщо хто-небудь ще мав проблеми з найкращим рішенням відповіді (включаючи відключення іноземних ключів), ось ще одне рішення від мене :

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

3

Не зовсім 1 запит, ще досить короткий і солодкий:

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

3

Використовуйте такий сценарій для dropвсіх 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

Потім запустіть наступне, щоб скинути всі таблиці:

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

Це працювало для мене у Azure SQL Database, де вона 'sp_msforeachtable'була недоступна!


1

Я знаю, що це запитання дуже давнє, але кожен раз, коли мені потрібен цей код .. до речі, якщо у вас є таблиці та перегляди, а також функції та ПРОЦЕДУРИ, ви можете видалити все це за допомогою сценарію .. так чому я публікую цей скрипт ?? тому що якщо ви видалите всі таблиці, вам потрібно буде видалити всі представлення даних, а якщо у вас є Функції та ПРОЦЕДУРИ, вам також потрібно видалити це,
я сподіваюся, що це комусь допоможе

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.