Как удалить все таблицы из базы данных одним SQL-запросом?

176

Я не хочу вводить имя всех таблиц, чтобы отбросить их все. Возможно ли с одним запросом?

Маджид
источник
3
Некоторый быстрый поиск в Google показал это: stackoverflow.com/questions/11053116/…
JSK NS
- хотя (для SQLServer) это может быть более полезным: stackoverflow.com/questions/536350/…
При правильном имени пользователя это может произойти автоматически ( обязательная ссылка xkcd ).
Minnow
11
У вас есть какие-нибудь внешние ключи для таблиц в базе данных? Если это так, вам нужно принять это во внимание и отбросить их, прежде чем пытаться удалить таблицы.
Энтони Грист
Имейте в виду, что если у вас есть привязанные к схеме объекты, вы не можете удалить таблицу.
Шон Ланге

Ответы:

177

Используйте представление 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"

Для получения дополнительной информации, проверьте здесь .

P ரதீப்
источник
3
(не мое отрицательное мнение) ... я бы обычно придерживался [sys]схемных представлений, если переносимость через rdbms 'не требуется. stackoverflow.com/a/3654313/251174
swasheck
1
Также см. Sqlblog.com/blogs/aaron_bertrand/archive/2011/11/03/…
Аарон Бертран
1
@DoubleA - это очень просто. Сначала я создаю операторы Drop для всех таблиц в моей базе данных и сохраняю их в переменную. Чтобы проверить это вы можете использовать Print @sqlраньше exec. Затем я выполняю динамически построенные операторы отбрасывания черезsp_executesql
P ரதீப்
2
Если вы используете Azure, sp_msforeachtable недоступен. Я нашел этот сладкий самородок от @Aaron Bertrand, чтобы удалить все ограничения FK. Работает очень хорошо с этим ответом. dba.stackexchange.com/questions/90033/…
trevorc
3
Если sp_msforeachtable недоступен, вы также можете выполнить запрос на удаление несколько раз, так как таблицы, которые зависят от других, затем удаляются :)
Maarten Kieft
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 раз и спецификацию. Это работает как шарм!
Альпер
1
@KyleVassella да, это будет выполняться только для базы данных, в которой у вас открыта консоль
RageAgainstTheMachine
39

Если вы не хотите печатать, вы можете создать операторы с помощью этого:

USE Databasename

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

Затем скопируйте и вставьте в новое окно SSMS, чтобы запустить его.

Dave.Gugg
источник
имя таблицы должно быть заключено в [], но прекрасно работает даже на 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
Silthus
источник
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;
Aerox
источник
4
Обычно я придерживаюсь представлений [sys]схемы, если не требуется переносимость через rdbms. stackoverflow.com/a/3654313/251174
swasheck
1
@swasheck Спасибо за ссылку, которая была довольно интересной. Я обновил ответ решением, использующим представления схемы sys.
AeroX 22.12.14
Вы можете использовать функцию 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'
OMA
источник
2
Я знаю, что оригинальный постер помечал вопрос с помощью «sql-server», но это может быть полезно для тех, кто хочет сделать это в MySQL. На самом деле я нашел этот вопрос, когда искал решение MySQL для этого вопроса, поэтому сейчас я делюсь решением, которое я нашел после прочтения одного из ответов здесь.
OMA
7

Самый простой способ - удалить всю базу данных и создать ее еще раз:

drop database db_name
create database db_name

Вот и все.

надзор
источник
1
:) по крайней мере для меня цель удаления всех таблиц состоит в том, что база данных не может быть удалена
Хасан Зафари
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
xx1xx
источник
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

Это работало для меня в базе данных SQL Azure, где '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
Aladein
источник