Excluir todos os dados no banco de dados SQL Server


Respostas:


194

A solução do SQLMenace funcionou para mim com um pequeno ajuste na maneira como os dados são excluídos - em DELETE FROMvez de 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

Eu To .. Consegui excluir, mas não truncar.
Marcel

17
Ele também pode fazer sentido para fazer um EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'após o DELETE FROM para repor todas as colunas de identidade de volta a 0.
Jonathan Alterar

1
É sempre um bom começo para o dia em que você encontra 6 linhas de código que substituem centenas de instruções de exclusão! Este método funciona sem problemas no SQL 2014 Express.
Tommy

1
Não se esqueça de gatilhos desativar aswell
Edwin Stoteler

10
Eu estava recebendo erro - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Para mim trabalhou:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Normalmente, usarei apenas o processo não documentado 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

Consulte também: Exclua todos os dados do banco de dados (quando você tiver FKs)


1
Eu não acho que isso funciona. Parece que Kalen Delaney foi inadvertidamente responsável por iniciar essa idéia. Aqui ela esclarece "você precisa eliminar a restrição de referência para truncar a tabela".
Martin Smith

Martin Acabei de executá-lo 2 segundos atrás no banco de dados Adventureworks sem problemas
SQLMenace 2/10/10

Definitivamente não funciona para mim aqui. create database testing; GO use testing; create table t1 (i int primary key) create table t2(i int primary key,p int references t1)
Martin Smith

2
Isso não funciona, apesar de ser marcado como a resposta. Definir restrição nocheck em chaves estrangeiras não permite executar comandos truncados nessas tabelas. Você ainda receberá erros que impedem que você trunque.
Quarta-

3
isso não funciona devido à presença de chaves estrangeiras. Ainda não consigo ver por que foi aceito como resposta: /
mounaim 15/09/14

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

script interessante, que não faz uso do processo armazenado não-desacompanhado 'sp_MSForEachTable', que está ausente no Azure. Precisa de ajustes se você tiver objetos em outro esquema que não seja [dbo].
Pac0

Use gist.github.com/metaskills/893599 para criar sp_MSForEachTable no Azure
Harpal

16

Estou ciente de que é tarde, mas concordo com a sugestão de AlexKuznetsov de criar um script para o banco de dados, em vez de passar pelo incômodo de eliminar os dados das tabelas. Se a TRUNCATEsolução não funcionar, e você tiver uma grande quantidade de dados, as DELETEinstruções de emissão (registradas) podem levar muito tempo e você ficará com identificadores que não foram reenviados (ou seja, uma INSERTdeclaração em uma tabela com uma IDENTITYcoluna obteria um ID 50000 em vez de 1).

Para criar um script de um banco de dados inteiro, no SSMS, clique com o botão direito do mouse no banco de dados e selecione TASKS-> Generate scripts:

insira a descrição da imagem aqui

Clique Nextpara ignorar a tela de abertura do Assistente e selecione quais objetos você deseja criar scripts:

insira a descrição da imagem aqui

Na Set scripting optionstela, você pode escolher configurações para o script, como gerar 1 script para todos os objetos ou separar scripts para os objetos individuais e salvar o arquivo em Unicode ou ANSI:

insira a descrição da imagem aqui

O assistente mostrará um resumo, que você pode usar para verificar se tudo está como desejado, e feche clicando em 'Concluir'.


Cuidado, pois assim, por padrão, você perderá itens como índices, se não for para o botão "Avançado".
glautrou

6
  1. Primeiro você terá que desativar todos os gatilhos:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Execute este script: (Retirado desta postagem Obrigado @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

Este script produzirá DELETEinstruções na ordem correta. começando em tabelas referenciadas e depois fazendo referência a

  1. Copie as DELETE FROMinstruções e execute-as uma vez

  2. ativar gatilhos

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Confirme as alterações:

    begin transaction
    commit;

Isso não funciona para mim, a consulta recursiva acaba em um loop. Talvez por causa de auto-reverências.
Edwin Stoteler

5

Geralmente, é muito mais rápido criar scripts para todos os objetos no banco de dados e criar um vazio, para excluir ou truncar tabelas.


3

Abaixo um script que eu usei para remover todos os dados de um banco de dados do 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

Como resposta alternativa, se você usa o Visual Studio SSDT ou possivelmente o Red Gate Sql Compare, você pode simplesmente executar uma comparação de esquema, fazer um script e descartar o banco de dados antigo (possivelmente faça um backup primeiro, caso exista um motivo que você precisará esses dados) e crie um novo banco de dados com o script criado pela ferramenta de comparação. Enquanto em um banco de dados muito pequeno isso pode dar mais trabalho, em um banco de dados muito grande, será muito mais rápido simplesmente descartá-lo e lidar com os diferentes gatilhos e restrições que possam estar no banco de dados.


-1

Sim, é possível excluir com uma única linha de código

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

Isso me dá uma nova tabela com uma instrução truncada para cada tabela. Na verdade, ele não exclui nada e, infelizmente, cuida do problema de eliminar as restrições primeiro. Pena que esperava uma resposta como essa, sem o uso de sp_MSForEachTable (que não existe para mim, Azure SQL Server)!
Pac0

sim. verdade. é criar um script truncado para todas as tabelas. Use esse script para excluir dados da tabela.
Buddhika De Silva 13/02/19

Essa solução funciona apenas no caso de não haver relacionamentos, pois não há como garantir que as tabelas sejam descartadas na ordem correta. Além disso, se houver algum gatilho nas exclusões de dados, isso poderá trazer consequências indesejadas.
dmoore1181
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.