Як скинути всі таблиці в базу даних SQL Server?


195

Я намагаюся написати сценарій, який повністю спорожнить базу даних SQL Server. Ось що я маю досі:

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

Коли я запускаю його в студії управління, я отримую:

Команди (и) успішно виконані.

але коли я оновлю список таблиць, вони все ще є. Що я роблю неправильно?


Якщо жодне з рішень на цій сторінці не працює, можливо, ви забули: USE [DatabaseName] GO
Serj Sagan

2
УДАЛИТИ? видалить записи з таблиці. Ви повинні використовувати DROP TABLE ?, але це не працюватиме з інших причин.
datagod

Відповіді:


306

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

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 він скаржиться на курсор?
Адам

11
Я отримую помилкуCould not find stored procedure 'sp_MSForEachTable'.
Korayem

2
Ця відповідь не працює, якщо у вас є таблиці (з обмеженнями) в іншій схемі, ніж dbo. Якщо у вас є власні схеми, вам потрібно змінити sql:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg

5
sp_MSforeachtableнедоступний у Azure. Використовуйте натомість відповідь @ CountZero.
Огглас

3
Знайдено цю посилання в Інтернеті (не моє): Копія sp_MS, що зберігається процедурою для Azure, використовує sp_MSforeach_worker: gist.github.com/metaskills/893599 .
Жоао Віейра

332

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

Я роблю цей крок за кроком так:

  1. Виберіть "Таблиці" в дереві бази даних (Провідник об'єктів)
  2. Натисніть клавішу F7, щоб відкрити перегляд Деталі про провідник об'єктів
  3. У цьому вікні виберіть таблиці, які потрібно видалити (у цьому випадку всі)
  4. Продовжуйте натискати Видалити, поки всі таблиці не будуть видалені (ви повторите це стільки разів, скільки кількість помилок через ключові обмеження / залежності)

5
Мені не вдалося змусити sp_msforeachtable працювати над Azure sql db. Я здогадуюсь, що вони не включають його в Azure. Це рішення чудово працює і ідеально підходить для глузування або внесення багатьох змін (починаючи з початку) з міграціями EF.
trevorc

Не враховує ФК / порядок.
Джош

1
це зручний метод, якщо вам просто потрібно це робити тут і там, сценарій може бути кращим, якщо ви робите це часто.
Ділан Хейс

2
@Josh порядок не враховується, але якщо ви продовжуєте натискати Гаразд у діалоговому вікні «Видалити», він продовжуватиме видалення всіх таблиць, які він може, з часом видалити всі таблиці.
clayRay

Ідеальне рішення з використанням дизайнера
Захер

49

У SSMS:

  • Клацніть правою кнопкою миші базу даних
  • Перейдіть до "Завдання"
  • Натисніть "Створити сценарії"
  • У розділі "Вибір об'єктів" виберіть "Сценарій всієї бази даних та всіх об'єктів бази даних"
  • У розділі "Встановити параметри сценарію" натисніть кнопку "Додатково"
  • У режимі "Скрипт і перетворення" перемкніть "Сценарій СТВОРИТИ" на "СТРАТИ ДРОП" та натисніть ОК
  • Потім збережіть у файл, буфер обміну або у новому вікні запиту.
  • Запустити сценарій.

Тепер це скине все, включаючи базу даних. Обов’язково видаліть код для предметів, які ви не хочете відкинути. Крім того, у розділі "Вибрати об'єкти" замість вибору сценарію всієї бази даних просто виберіть елементи, які потрібно видалити.


3
Якщо ви не хочете скидати базу даних (що, в моєму випадку, мені не так, як мені тоді потрібно зробити виклик підтримки, щоб її створити), тоді використовуйте "Вибрати конкретні об'єкти бази даних" та виберіть усі типи об'єктів, які ти хочеш кинути.
d219

3
Це найпростіший спосіб.
Асірі Діссанаяка

2
Це має бути відповідь точно!
Зак Тейлор

34

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

EXEC sp_msforeachtable 'drop table [?]'

Це, здавалося, вирішило проблему не мати жодних помилок, але тепер я стикаюся з помилками обмеження. Чи синтаксис мого NOCHECK CONSTRAINTрядка неправильний?
dixuji

1
Я використовував це на швидких 2 таблицях з FK, і це спрацювало. EXEC sp_msforeachtable 'ALTER TABLE? NOCHECK CONSTRAINT all '
DaveShaw

12
Це працювало для мене лише після того, як я видалив квадратні дужки: EXEC sp_msforeachtable 'drop table?'.
LPains

На SQL Server вам потрібні дужки, якщо будь-яке ім’я таблиці має будь-які непарні символи або пробіли. Я не знав версії SQL Server, яка не підтримувала дужки навколо імен об'єктів.
DaveShaw

На SQL Server 2012 (11.x) мені також довелося видалити квадратні дужки.
Фрідер

30

Прийнята відповідь не підтримує 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)
Liam Dawson,

21

Ви майже маєте рацію, використовуйте натомість:

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як перший рядок. Працював як шарм.
Саймон Собіш

Коротке і солодке! Thnx.
sapatelbaps

7

Швидкий спосіб:

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

Це, безумовно, найшвидший, менш схильний до помилок спосіб. Це має бути прийнятою відповіддю.
DARKGuy


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

2

Пляма на!!

Ви можете скористатися запитом нижче, щоб видалити всі таблиці з бази даних

EXEC sp_MSforeachtable @ command1 = "ЗРОБИТИ ТАБЛИЦЮ?"

Щасливого кодування!


1

Як щодо скидання всієї бази даних, а потім її створення знову? Це працює для мене.

DROP DATABASE mydb;
CREATE DATABASE mydb;

Чи не потрібно розміщувати файли mdf та ldf між ними?
ruffin

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

2
Це дійсно залежить від обставин. У моєму випадку у мене немає збережених процедур, і цей метод працює для мене чудово. Я не збираюся писати складні коди, які охоплюють десятки рядків, коли це робитимуть два рядки. Я не думаю, що моя відповідь не виправдовує негативу, оскільки я пропоную пропозицію певній групі користувачів.
Chong Lip Phang

0

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

Врешті-решт я придумав це. Я перевіряв це скрізь (взагалі кажучи), можу, і це працює (без будь-яких прихованих процедур зберігання).

Для замітки в основному на SQL Server 2014. (але більшість інших версій, які я пробував, також, здається, працювали нормально).

Я намагався в той час, як цикли, нулі і т. Д. І т.д., курсори та інші інші форми, але вони, здається, завжди виходять з ладу в деяких базах даних, але не в інших без жодної видимої причини.

Отримати підрахунок та використовувати його для ітерації завжди, здається, працює над усім, що я перевірив.

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.