Como soltar todas as tabelas em um banco de dados SQL Server?

195

Estou tentando escrever um script que esvaziará completamente um banco de dados do SQL Server. Isto é o que eu tenho até agora:

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

Quando o executo no Management Studio, recebo:

Comando (s) concluído (s) com sucesso.

mas quando eu atualizo a lista de tabelas, elas ainda estão lá. O que estou fazendo de errado?

dixuji
fonte
Se nenhuma das soluções desta página estiver funcionando, talvez você tenha esquecido de: USE [DatabaseName] GO
Serj Sagan
2
EXCLUIR? excluirá os registros da tabela. Você deve usar DROP TABLE?, No entanto, isso não funcionará por outros motivos.
datagod

Respostas:

305

Também não funciona para mim quando existem várias tabelas de chaves estrangeiras.
Encontrei o código que funciona e faz tudo o que você tenta (exclua todas as tabelas do seu banco de dados):

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

Você pode encontrar o post aqui . É o post do Groker.

Gabriel GM
fonte
Por que é quando você tenta agrupar todo esse bloco de código em uma instrução IF usando um bloco BEGIN-END que reclama sobre o cursor?
Adam
11
Estou recebendo erroCould not find stored procedure 'sp_MSForEachTable'.
Korayem
2
Esta resposta não funcionará se você tiver tabelas (com restrições) em um esquema diferente de dbo. Se você tiver esquemas personalizados, precisará alterar o sqlpara:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg
5
sp_MSforeachtablenão está disponível no Azure. Use a resposta do @ CountZero.
Ogglas
3
Encontrei esta referência na Web (não a minha): Uma cópia do procedimento armazenado sp_MSforeachtable Para o Azure, usa sp_MSforeach_worker: gist.github.com/metaskills/893599 .
João Vieira
330

Você também pode excluir todas as tabelas do banco de dados usando apenas as ferramentas de interface do usuário MSSMS (sem usar o script SQL). Às vezes, esse caminho pode ser mais confortável (especialmente se for realizado ocasionalmente)

Eu faço isso passo a passo da seguinte maneira:

  1. Selecione 'Tabelas' na árvore do banco de dados (Pesquisador de Objetos)
  2. Pressione F7 para abrir a exibição Detalhes do Pesquisador de Objetos
  3. Nesta visão, selecione as tabelas que precisam ser excluídas (neste caso, todas elas)
  4. Continue pressionando Excluir até que todas as tabelas tenham sido excluídas (você a repete quantas vezes houver devido a restrições / dependências de teclas)
Bronek
fonte
5
Não foi possível obter sp_msforeachtable para trabalhar em um banco de dados sql do Azure. Suponho que eles não o incluam no Azure. Esta solução funciona muito bem e é perfeita ao zombar ou fazer muitas alterações (iniciando novamente) com migrações EF.
trevorc
Não considera FKs / pedido.
28416 Josh
1
esse é um método útil, se você precisar fazer aqui e ali, o script poderá ser melhor se você o fizer com frequência.
Dylan Hayes
2
@Josh, o pedido não é considerado, mas se você pressionar Ok na caixa de diálogo Excluir, ele continuará excluindo todas as tabelas que puder, o que acabará por excluir todas as tabelas.
precisa saber é o seguinte
Perfect Solution usando Designer
Zaheer
48

No SSMS:

  • Clique com o botão direito do mouse no banco de dados
  • Vá para "Tarefas"
  • Clique em "Gerar scripts"
  • Na seção "Escolher objetos", selecione "Script de banco de dados inteiro e todos os objetos de banco de dados"
  • Na seção "Definir opções de script", clique no botão "Avançado"
  • Em "Script DROP and CREATE" alterne "Script CREATE" para "Script DROP" e pressione OK
  • Em seguida, salve em arquivo, área de transferência ou nova janela de consulta.
  • Execute o script.

Agora, isso eliminará tudo, incluindo o banco de dados. Certifique-se de remover o código dos itens que não deseja que sejam descartados. Como alternativa, na seção "Escolher objetos", em vez de selecionar o script do banco de dados inteiro, basta selecionar os itens que você deseja remover.

Ben
fonte
3
Se você não deseja descartar o banco de dados (o que, no meu caso, não é o caso, eu precisaria fazer uma chamada de suporte para criá-lo), use 'Selecionar objetos específicos do banco de dados' e selecione todos os tipos de objetos que você deseja largar.
d219 27/07/18
3
Esta é a maneira mais fácil.
Asiri Dissanayaka
2
Esta deve ser a resposta, com certeza!
Zac Taylor
34

deleteé usado para excluir linhas de uma tabela. Você deve usar em seu drop tablelugar.

EXEC sp_msforeachtable 'drop table [?]'
DaveShaw
fonte
Isso parecia ter corrigido o problema de não haver erros, mas agora estou enfrentando erros de restrição. A sintaxe da minha NOCHECK CONSTRAINTlinha está errada?
dixuji
1
Eu usei isso em uma rápida 2 mesas com FK e funcionou. EXEC sp_msforeachtable 'ALTER TABLE? NOCHECK CONSTRAINT all '
DaveShaw
12
Isso só funcionou para mim depois que removi os colchetes: EXEC sp_msforeachtable 'drop table?'.
LPains
No SQL Server, você precisa dos colchetes se qualquer nome de tabela tiver caracteres ou espaços ímpares. Eu não conhecia uma versão do SQL Server que não suporta colchetes em torno de nomes de objetos.
DaveShaw
No SQL Server 2012 (11.x), também tive que remover os colchetes.
Frieder
30

A resposta aceita não oferece suporte ao Azure. Ele usa um procedimento armazenado não documentado "sp_MSforeachtable". Se você receber um erro "o azure não pôde encontrar o procedimento armazenado 'sp_msforeachtable" ao executar ou simplesmente deseja evitar confiar em recursos não documentados (que podem ser removidos ou que sua funcionalidade foi alterada a qualquer momento), tente o abaixo.

Esta versão ignora a tabela de histórico de migração da estrutura da entidade "__MigrationHistory" e o "database_firewall_rules", que é uma tabela do Azure que você não terá permissão para excluir.

Levemente testado no Azure. Verifique se isso não tem efeitos indesejados no seu ambiente.

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

Tirado de:

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/

CountZero
fonte
3
Trabalhou como mágica no azul. Muito mais rápido, em seguida, removendo via interface do VS
Simeon Grigorovich
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
Harpal
fonte
1
Funciona no SQL Azure :) sp_MSforeachtable não funciona lá
Pavel Biryukov
Como uma observação, isso irá falhar se você tiver esquemas que não sejam do dbo (por exemplo, se você estiver usando o Hangfire)
Liam Dawson
21

Você está quase certo, use:

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

mas na segunda linha, você pode precisar executar mais de uma vez até parar de receber erro:

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

Mensagem:

Command(s) completed successfully.

significa que todas as tabelas foram excluídas com sucesso.

Michał Powaga
fonte
17

Curto e grosso:

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
xx1xx
fonte
2
Eu tive que substituir sp_msforeachtablepor sp_MSforeachtablee recomendo adicionar um use yourdatabasecomo primeira linha. Funcionou como um encanto.
Simon Sobisch
Curto e grosso! Thnx.
sapatelbaps 7/02/19
7

O caminho do jejum é:

  1. Novos diagramas de banco de dados
  2. Adicionar toda a tabela
  3. Ctrl + A para selecionar todos
  4. Clique com o botão direito em "Remover do banco de dados"
  5. Ctrl + S para salvar
  6. Aproveitar
TuanDPH
fonte
Esta é de longe a maneira mais rápida e menos propensa a erros de fazer isso. Essa deve ser a resposta aceita.
DARKGuy
6

Parece que o comando deve estar sem o cobertor quadrado

EXEC sp_msforeachtable 'drop table ?'
Jimmy Wong
fonte
6

Para mim, a maneira mais fácil:

--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 ?'
Jeffrey
fonte
2

Spot on !!

Você pode usar a consulta abaixo para remover todas as tabelas do banco de dados

EXEC sp_MSforeachtable @ command1 = "DROP TABLE?"

Feliz codificação!

Gajanan Kulkarni
fonte
1

Que tal descartar o banco de dados inteiro e criá-lo novamente? Isso funciona para mim.

DROP DATABASE mydb;
CREATE DATABASE mydb;
Chong Lip Phang
fonte
Você não precisa explodir os arquivos mdf e ldf no meio?
Ruffin
Estou usando um provedor de host e não tenho muita certeza disso. Eu acho que esses arquivos serão excluídos automaticamente quando você soltar um banco de dados, a menos que esteja offline.
Chong Lip Phang
2
Realmente depende das circunstâncias. No meu caso, não tenho procedimentos armazenados e esse método funciona bem para mim. Não vou escrever códigos complexos que abrangem dezenas de linhas quando duas linhas serão suficientes. Não acho que minha resposta justifique um voto negativo, pois ofereço uma sugestão a um grupo específico de usuários.
Chong Lip Phang
0

Sei que agora é uma publicação antiga, mas tentei todas as respostas aqui em vários bancos de dados e descobri que todas elas funcionam às vezes, mas não o tempo todo, para várias peculiaridades (só posso assumir) do SQL Server.

Eventualmente, eu vim com isso. Eu testei isso em todos os lugares (em geral) que posso e funciona (sem nenhum procedimento de armazenamento oculto).

Para observação principalmente no SQL Server 2014. (mas a maioria das outras versões que tentei também parece funcionar bem).

Eu tentei enquanto loops e nulos etc etc, cursores e várias outras formas, mas eles sempre parecem falhar em alguns bancos de dados, mas não em outros, sem motivo óbvio.

Obter uma contagem e usá-la para iterar sempre parece funcionar em tudo que eu testei.

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
William Humphreys
fonte
0

Para tabelas temporais , é um pouco mais complicado, pois pode haver algumas chaves estrangeiras e também a exceção:

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

O que você pode usar é:

-- 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
J.Wincewicz
fonte