Удалить все данные в базе данных 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)'после DELETE FROM, чтобы сбросить все столбцы идентификаторов обратно на 0.
Джонатан Поправка

1
Это всегда хорошее начало дня, когда вы найдете 6 строк кода, заменяющих сотни операторов удаления! Этот метод работает без проблем в 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 ?'
каси

36

Обычно я просто использую недокументированную процедуру 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
Это не работает, несмотря на то, что он отмечен как ответ. Установка ограничения nocheck для внешних ключей не позволяет запускать команды усечения для этих таблиц. Вы по-прежнему будете получать ошибки, которые не позволят вам выполнить усечение.
Четвертое

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 Compare, вы можете просто запустить сравнение схемы, выполнить сценарий, удалить старую базу данных (возможно, сначала сделайте резервную копию, если возникнет причина, по которой вам понадобится эти данные), а затем создайте новую базу данных со сценарием, созданным инструментом сравнения. В то время как в очень маленькой базе данных это может потребовать больше работы, в очень большой базе данных будет намного быстрее просто удалить базу данных, чем иметь дело с различными триггерами и ограничениями, которые могут быть в базе данных.


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