Как удалить все таблицы в базе данных SQL Server?


204

Я пытаюсь написать сценарий, который полностью очистит базу данных SQL Server. Вот что у меня есть на данный момент:

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

Когда я запускаю его в Management Studio, я получаю:

Команды успешно выполнены.

но когда я обновляю список таблиц, они все еще там. Что я делаю не так?


Если ни одно из решений на этой странице не работает, возможно, вы забыли: USE [DatabaseName] GO
Серж Саган

2
УДАЛЯТЬ ? удалит записи из таблицы. Вы должны использовать DROP TABLE ?, но это не сработает по другим причинам.
datagod

Обязательное чтение: xkcd.com/327
Краун

Ответы:


320

У меня тоже не работает, когда есть несколько таблиц внешних ключей.
Я нашел этот код, который работает и делает все, что вы пытаетесь (удалите все таблицы из базы данных):

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

Вы можете найти сообщение здесь . Это сообщение Грокера.


Почему, когда вы пытаетесь обернуть весь этот блок кода в операторе IF, используя блок BEGIN-END, он жалуется на курсор?
Adam

12
Я получаю ошибкуCould not find stored procedure 'sp_MSForEachTable'.
Кораем

2
Этот ответ не работает, если у вас есть таблицы (с ограничениями) в другой схеме, чем dbo. Если у вас есть собственные схемы, вам необходимо изменить их sqlна:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg,

6
sp_MSforeachtableнедоступен в Azure. Вместо этого используйте ответ @ CountZero.
Ogglas

3
Нашел эту ссылку в Интернете (не мою): Копия хранимой процедуры sp_MSforeachtable для Azure, использует sp_MSforeach_worker: gist.github.com/metaskills/893599 .
Жуан Виейра

346

Вы также можете удалить все таблицы из базы данных, используя только инструменты пользовательского интерфейса MSSMS (без использования сценария SQL). Иногда такой способ может быть более комфортным (особенно если он выполняется от случая к случаю).

Я делаю это поэтапно следующим образом:

  1. Выберите «Таблицы» в дереве базы данных (обозреватель объектов)
  2. Нажмите F7, чтобы открыть представление «Подробности обозревателя объектов».
  3. В этом представлении выберите таблицы, которые необходимо удалить (в данном случае все)
  4. Продолжайте нажимать Delete, пока все таблицы не будут удалены (вы повторяете это столько раз, сколько ошибок из-за ключевых ограничений / зависимостей)

6
Мне не удалось заставить sp_msforeachtable работать с базой данных SQL Azure. Я предполагаю, что они не включают его для Azure. Это решение отлично работает и идеально подходит для имитации или внесения большого количества изменений (начиная с) с миграциями EF.
Trevorc

Не учитывает ФК / заказ.
Джош

1
это удобный метод, если вам просто нужно делать это здесь и там, сценарий может быть лучше, если вы делаете это часто.
Дилан Хейс

2
@Josh порядок не учитывается, но если вы продолжите нажимать Ok в диалоговом окне «Удалить», он продолжит удаление всех возможных таблиц, что в конечном итоге приведет к удалению всех таблиц.
ClayRay 01

Идеальное решение с использованием конструктора
Захир

61

В SSMS:

  • Щелкните правой кнопкой мыши базу данных
  • Перейти в "Задачи"
  • Нажмите «Создать сценарии».
  • В разделе «Выбрать объекты» выберите «Сценарий всей базы данных и всех объектов базы данных».
  • В разделе «Установить параметры сценария» нажмите кнопку «Дополнительно».
  • В «Script DROP and CREATE» переключите «Script CREATE» на «Script DROP» и нажмите OK.
  • Затем либо сохраните в файл, либо в буфер обмена, либо в новое окно запроса.
  • Запустить скрипт.

Теперь это отбросит все, включая базу данных. Не забудьте удалить код для предметов, которые вы не хотите уронить. В качестве альтернативы, в разделе «Выбор объектов» вместо выбора сценария для всей базы данных просто выберите элементы, которые вы хотите удалить.


4
Если вы не хотите отбрасывать базу данных (что в моем случае я не делаю, так как тогда мне нужно было бы позвонить в службу поддержки, чтобы создать ее), используйте «Выбрать определенные объекты базы данных» и выберите все типы объектов, вы хотите бросить.
d219

4
Это самый простой способ.
Асири Диссанаяка

3
Это должен быть ответ!
Зак Тейлор

37

deleteиспользуется для удаления строк из таблицы. drop tableВместо этого вы должны использовать .

EXEC sp_msforeachtable 'drop table [?]'

Это, казалось, устранило проблему отсутствия ошибок, но теперь я сталкиваюсь с ошибками ограничений. Синтаксис моей NOCHECK CONSTRAINTстроки неправильный?
dixuji

1
Я использовал это на двух быстрых столах с FK, и это сработало. EXEC sp_msforeachtable 'ALTER TABLE? NOCHECK CONSTRAINT all '
DaveShaw

14
У меня это сработало только после того, как я удалил квадратные скобки: EXEC sp_msforeachtable 'drop table?'.
LPains

В SQL Server скобки нужны, если имя какой-либо таблицы содержит нечетные символы или пробелы. Мне не известна версия SQL Server, которая не поддерживает скобки вокруг имен объектов.
DaveShaw,

В SQL Server 2012 (11.x) мне также пришлось удалить квадратные скобки.
Frieder

32

Принятый ответ не поддерживает Azure. Он использует недокументированную хранимую процедуру sp_MSforeachtable. Если вы получаете сообщение об ошибке «Azure не удалось найти хранимую процедуру sp_msforeachtable» при запуске или просто хотите избежать использования недокументированных функций (которые можно удалить или изменить их функциональность в любой момент), попробуйте следующее.

Эта версия игнорирует таблицу истории миграции структуры сущностей «__MigrationHistory» и «database_firewall_rules», которая представляет собой таблицу Azure, на удаление которой у вас не будет разрешения.

Слегка протестирован в Azure. Убедитесь, что это не оказывает нежелательного воздействия на вашу среду.

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

Взято из:

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/


3
Колдовал над лазурью. Намного быстрее, чем удаление через интерфейс VS
Симеон Григорович

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

1
Работает в SQL Azure :) sp_MSforeachtable там не работает
Павел Бирюков

Обратите внимание: это не сработает, если у вас есть схемы, отличные от dbo (например, если вы используете Hangfire)
Лиам Доусон,

23

Вы почти правы, используйте вместо этого:

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

но вторую строку вам может потребоваться выполнить более одного раза, пока вы не перестанете получать ошибку:

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

Сообщение:

Command(s) completed successfully.

означает, что вся таблица была успешно удалена.


17

Коротко и мило:

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

2
Мне пришлось заменить sp_msforeachtableна, sp_MSforeachtableи я настоятельно рекомендую добавить в use yourdatabaseкачестве первой строки. Работал как шарм.
Саймон Собиш

Коротко и мило! Спасибо.
sapatelbaps


6

Быстрый способ:

  1. Новые диаграммы базы данных
  2. Добавить всю таблицу
  3. Ctrl + A, чтобы выделить все
  4. Щелкните правой кнопкой мыши «Удалить из базы данных».
  5. Ctrl + S для сохранения
  6. наслаждаться

Это, безусловно, самый быстрый и менее подверженный ошибкам способ сделать это. Это должен быть принятый ответ.
DARKGuy

Может быть, потому что он вылетает, когда много столов
AriesConnolly,

6

Для меня самый простой способ:

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

4

Пятно !!

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

EXEC sp_MSforeachtable @ command1 = "УДАЛИТЬ ТАБЛИЦУ?"

Удачного кодирования!


Выполнено несколько раз. и, наконец, удалили все таблицы.
ДЖИВАН ДЖОРДЖ АНТОНИ,

Думаю, нужно делать только один раз.
Гаджанан Кулкарни

У меня было несколько таблиц с иностранными ключами и все такое. При одиночном исполнении это не сработало. но, выполнив его несколько раз, мне пришлось удалить все таблицы.
ДЖИВАН ДЖОРДЖ АНТОНИ

1

Как насчет того, чтобы удалить всю базу данных, а затем создать ее снова? У меня это работает.

DROP DATABASE mydb;
CREATE DATABASE mydb;

Разве вам не нужно взрывать файлы mdf и ldf между ними?
ruffin

Я использую провайдера веб-хостинга, и я не уверен в этом. Я думаю, что эти файлы будут автоматически удалены при удалении базы данных, если вы не находитесь в автономном режиме.
Chong Lip Phang

2
Это действительно зависит от обстоятельств. В моем случае у меня нет хранимых процедур, и этот метод мне подходит. Я не собираюсь писать сложные коды, охватывающие десятки строк, когда достаточно двух строк. Я не думаю, что мой ответ оправдывает отрицательный голос, поскольку я предлагаю предложение определенной группе пользователей.
Чонг Лип Панг

0

Я знаю, что это старый пост, но я попробовал все ответы здесь на множестве баз данных, и я обнаружил, что все они иногда работают, но не все время для различных (я могу только предположить) причуд SQL Server.

В конце концов я придумал это. Я тестировал это везде (вообще говоря), и это работает (без каких-либо скрытых процедур хранения).

Обратите внимание, в основном на SQL Server 2014. (но большинство других версий, которые я пробовал, также, похоже, работали нормально).

Я пробовал циклы while, нули и т. Д., Курсоры и различные другие формы, но они всегда, кажется, терпят неудачу в некоторых базах данных, но не в других без очевидной причины.

Получение подсчета и его использование для итерации всегда работает во всем, что я тестировал.

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

0

Для временных таблиц это немного сложнее из-за того, что могут быть некоторые внешние ключи, а также исключение:

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

Что вы можете использовать:

-- 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.