Видаліть усі дані з бази даних SQL Server


129

Як я можу видалити всі записи з усіх таблиць моєї бази даних? Чи можу я це зробити з однією командою SQL або мені потрібна одна команда SQL для однієї таблиці?

Відповіді:


194

Рішення SQLMenace працювало на мене, дещо змінившись тим, як видаляються дані - DELETE FROMзамість TRUNCATE.

-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'DELETE FROM ?' 
GO 

-- enable referential integrity again 
EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL' 
GO

Me To .. Мені вдалося видалити, але не скорочувати.
Марсель

17
Можливо, також є сенс зробити EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'«УДАЛИТИ ВІД», щоб скинути всі стовпці особи назад до 0.
Джонатан Поправка

1
Це завжди хороший початок дня, коли ви знайдете 6 рядків коду, який замінює 100-ти виписок видалення! Цей метод працює без проблем на SQL 2014 Express.
Томмі

1
Не забудьте також відключити тригери
Едвін Стотелер,

10
Я отримував помилку - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Для мене працювали:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Зазвичай я просто використовуватиму незадокументований proc sp_MSForEachTable

-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?' 
GO 

-- enable referential integrity again 
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 
GO

Дивіться також: Видаліть усі дані з бази даних (коли у вас є FK)


1
Я не думаю, що це працює. Схоже, Кален Делані ненавмисно відповідав за те, щоб почати цю ідею. Тут вона уточнює: "Ви повинні скинути обмеження посилань, щоб усікати таблицю".
Мартін Сміт

Мартін я щойно запустив це 2 секунди тому в БД Adventureworks без проблем
SQLMenace

Тут для мене це точно не працює. create database testing; GO use testing; create table t1 (i int primary key) create table t2(i int primary key,p int references t1)
Мартін Сміт

2
Це не працює, незважаючи на те, що було позначено як відповідь. Встановлення обмеження ніч-позначки на зовнішніх клавішах не дозволяє запускати команди скорочення на цих таблицях. Ви все одно отримаєте помилки, які не дозволяють вам обрізатися.
Четверте

3
це не працює через наявність сторонніх ключів. Досі не можу зрозуміти, чому це було прийнято як відповідь: /
mounaim

19
/* 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

цікавий сценарій, який не використовує непідготовлену збережену програму "sp_MSForEachTable", якої немає в Azure. Потрібно налаштувати, якщо у вас є об'єкти на іншій схемі, ніж [dbo].
Pac0

Будь ласка, використовуйте gist.github.com/metaskills/893599 для створення sp_MSForEachTable у Azure
Harpal

16

Я знаю, що це пізно, але я погоджуюся з пропозицією Алекс Кузнецова написати сценарій бази даних, а не переживати проблеми з очищенням даних із таблиць. Якщо TRUNCATEрішення не працює, і у вас є великий обсяг даних, видача (вхід у журнал) DELETEможе зайняти тривалий час, і вам залишиться ідентифікатори, які не були перезавантажені (тобто INSERTвиписка в таблицю з IDENTITYстовпець отримає вам ідентифікатор 50000. замість ідентифікатора 1).

Для скриптування всієї бази даних в SSMS правою кнопкою миші клацніть на базі даних, а потім виберіть TASKS-> Generate scripts:

введіть тут опис зображення

Клацніть, Nextщоб пропустити екран відкриття Майстра, а потім виберіть, які об’єкти ви хочете сценарію:

введіть тут опис зображення

На Set scripting optionsекрані ви можете вибрати параметри сценаріїв, наприклад, генерувати 1 сценарій для всіх об'єктів, або окремі сценарії для окремих об'єктів та зберегти файл у Unicode чи ANSI:

введіть тут опис зображення

Майстер покаже резюме, за допомогою якого ви зможете перевірити все, як бажано, і закрийте, натиснувши "Готово".


Будьте уважні, таким чином за замовчуванням ви втратите такі речі, як індекси, якщо не перейдете до кнопки «Додатково».
glautrou

6
  1. Спочатку доведеться відключити всі тригери:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Запустіть цей сценарій: (взято з цієї публікації Дякую @SQLMenace)

    SET NOCOUNT ON
    GO
    
    SELECT 'USE [' + db_name() +']';
    ;WITH a AS 
    (
         SELECT 0 AS lvl, 
                t.object_id AS tblID 
         FROM sys.TABLES t
         WHERE t.is_ms_shipped = 0
           AND t.object_id NOT IN (SELECT f.referenced_object_id 
                                   FROM sys.foreign_keys f)
    
         UNION ALL
    
         SELECT a.lvl + 1 AS lvl, 
                f.referenced_object_id AS tblId
         FROM a
         INNER JOIN sys.foreign_keys f ON a.tblId = f.parent_object_id 
                                       AND a.tblID <> f.referenced_object_id
    )
    SELECT 
        'Delete from ['+ object_schema_name(tblID) + '].[' + object_name(tblId) + ']' 
    FROM a
    GROUP BY tblId 
    ORDER BY MAX(lvl),1

Цей сценарій буде створювати DELETEзаяви у належному порядку. починаючи з посиланих таблиць, а потім посилаючись на ті

  1. Скопіюйте DELETE FROMзаяви і запустіть їх один раз

  2. включити тригери

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Внести зміни:

    begin transaction
    commit;

Це не працює для мене, рекурсивний запит закінчується в циклі. Можливо, через самоповагу.
Едвін Стотелер

5

Зазвичай набагато швидше скриптувати всі об'єкти в базі даних і створити порожній, який можна видалити з або скоротити таблиці.


3

Нижче сценарій, який я використовував для видалення всіх даних із бази даних SQL Server

------------------------------------------------------------
/* Use database */ 
-------------------------------------------------------------

use somedatabase;

GO

------------------------------------------------------------------
/* Script to delete an repopulate the base [init database] */
------------------------------------------------------------------

-------------------------------------------------------------
/* Procedure delete all constraints */ 
-------------------------------------------------------------

IF EXISTS (SELECT name  
           FROM  sysobjects 
           WHERE name = 'sp_DeleteAllConstraints' AND type = 'P')
    DROP PROCEDURE dbo.sp_DeleteAllConstraints
GO

CREATE PROCEDURE sp_DeleteAllConstraints
AS
    EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
    EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
GO

-----------------------------------------------------
/* Procedure delete all data from the database */ 
-----------------------------------------------------

IF EXISTS (SELECT name  
           FROM  sysobjects 
           WHERE name = 'sp_DeleteAllData' AND type = 'P')
    DROP PROCEDURE dbo.sp_DeleteAllData
GO

CREATE PROCEDURE sp_DeleteAllData
AS
    EXEC sp_MSForEachTable 'DELETE FROM ?'
GO

-----------------------------------------------
/* Procedure enable all constraints */ 
-----------------------------------------------

IF EXISTS (SELECT name  
           FROM  sysobjects 
           WHERE name = 'sp_EnableAllConstraints' AND type = 'P')
    DROP PROCEDURE dbo.sp_EnableAllConstraints
GO
-- ....
-- ....
-- ....

1
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'

EXEC sp_MSForEachTable 'DELETE FROM ?'

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'

EXEC sp_MSFOREACHTABLE 'SELECT * FROM ?'

GO

0

В якості альтернативної відповіді, якщо ви Visual Studio SSDT або можливо Red Gate Sql Порівняти, ви можете просто запустити порівняння схеми, відключити сценарій, скинути стару базу даних (можливо, спершу зробити резервну копію, якщо буде причина, що вам знадобиться ці дані), а потім створити нову базу даних із скриптом, створеним інструментом порівняння. Хоча на дуже невеликій базі даних це може бути більше роботи, але на дуже великій базі даних буде набагато швидше просто відкинути базу даних, а потім вирішити різні тригери та обмеження, які можуть бути в базі даних.


-1

Так, можна видалити за допомогою одного рядка коду

SELECT 'TRUNCATE TABLE ' + d.NAME + ';' 
FROM   sys.tables d 
WHERE  type = 'U' 

Це дає мені нову таблицю із скороченням для кожної таблиці. Він насправді нічого не видаляє, і, на жаль, спочатку вирішує проблему скасування обмежень. Шкода, я сподівався на таку відповідь без використання sp_MSForEachTable (який для мене не існує, Azure SQL Server)!
Pac0

так. правда. його сценарій створення усікання для всіх таблиць. Використовуйте цей сценарій для видалення даних таблиць.
Буддхіка Де Сільва

Це рішення працює лише в тому випадку, якщо немає взаємин, оскільки воно не може гарантувати, що таблиці будуть скинуті в правильному порядку. Крім того, якщо є якісь тригери для видалення даних, це може спричинити ненавмисні наслідки.
dmoore1181
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.