Come eliminare tutte le tabelle in un database di SQL Server?


196

Sto cercando di scrivere uno script che svuoterà completamente un database di SQL Server. Questo è quello che ho finora:

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

Quando lo eseguo in Management Studio, ottengo:

Comandi completati correttamente.

ma quando aggiorno l'elenco delle tabelle, sono ancora tutti lì. Che cosa sto facendo di sbagliato?


Se nessuna delle soluzioni in questa pagina funziona, forse ti sei dimenticato di: USE [DatabaseName] GO
Serj Sagan,

2
ELIMINA ? eliminerà i record dalla tabella. Dovresti usare DROP TABLE?, Tuttavia ciò non funzionerà per altri motivi.
datagod

Risposte:


306

Non funziona neanche per me quando ci sono più tabelle di chiavi esterne.
Ho trovato quel codice che funziona e fa tutto ciò che provi (elimina tutte le tabelle dal tuo database):

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

Puoi trovare il post qui . È il post di Groker.


Perché quando provi a racchiudere l'intero blocco di codice in un'istruzione IF usando un blocco BEGIN-END, si lamenta del cursore?
Adam,

11
Ricevo un erroreCould not find stored procedure 'sp_MSForEachTable'.
Korayem,

2
Questa risposta non funziona se si dispone di tabelle (con vincoli) in uno schema diverso da dbo. Se si dispone di schemi personalizzati, è necessario modificare sql:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg

5
sp_MSforeachtablenon è disponibile in Azure. Usa invece la risposta di @ CountZero.
Ogglas,

3
Trovato questo riferimento sul Web (non mio): una copia di sp_MSforeachtable stored procedure per Azure, utilizza sp_MSforeach_worker: gist.github.com/metaskills/893599 .
João Vieira,

333

È inoltre possibile eliminare tutte le tabelle dal database utilizzando solo gli strumenti dell'interfaccia utente MSSMS (senza utilizzare lo script SQL). A volte in questo modo può essere più comodo (soprattutto se eseguito occasionalmente)

Faccio questo passo per passo come segue:

  1. Seleziona "Tabelle" nella struttura del database (Esplora oggetti)
  2. Premere F7 per aprire la vista Dettagli Esplora oggetti
  3. In questa vista selezionare le tabelle che devono essere eliminate (in questo caso tutte)
  4. Continua a premere Elimina fino a quando tutte le tabelle non sono state eliminate (lo ripeti tante volte quante sono le quantità di errori dovute a vincoli / dipendenze chiave)

5
Non sono riuscito a far funzionare sp_msforeachtable su un database sql di Azure. Immagino che non lo includano per Azure. Questa soluzione funziona alla grande ed è perfetta per deridere o apportare molte modifiche (ricominciare da capo) con le migrazioni EF.
trevorc,

Non considera gli FK / l'ordine.
Josh,

1
questo è un metodo utile se hai solo bisogno di farlo qua e là, lo script potrebbe essere migliore se lo fai spesso.
Dylan Hayes,

2
@Josh l'ordine non è considerato, ma se continui a premere Ok nella finestra di dialogo Elimina continuerà a eliminare tutte le tabelle che può, che alla fine eliminerà tutte le tabelle.
clayRay

Soluzione perfetta con Designer
Zaheer

50

In SSMS:

  • Fare clic con il tasto destro del mouse sul database
  • Vai a "Attività"
  • Fai clic su "Genera script"
  • Nella sezione "Scegli oggetti", seleziona "Script intero database e tutti gli oggetti del database"
  • Nella sezione "Imposta opzioni di scripting", fai clic sul pulsante "Avanzate"
  • Su "Script DROP e CREATE", passare "Script CREATE" su "Script DROP" e premere OK
  • Quindi, salva su file, appunti o nuova finestra di query.
  • Esegui script.

Ora, questo lascerà cadere tutto, incluso il database. Assicurati di rimuovere il codice per gli elementi che non desideri vengano rilasciati. In alternativa, nella sezione "Scegli oggetti", invece di selezionare lo script per l'intero database basta selezionare gli elementi che si desidera rimuovere.


4
Se non si desidera eliminare il database (che nel mio caso non è come avrei dovuto effettuare una chiamata di supporto per crearlo), utilizzare "Seleziona oggetti specifici del database" e selezionare tutti i tipi di oggetto che vuoi cadere.
d219

4
Questo è il modo più semplice.
Asiri Dissanayaka,

3
Questa dovrebbe essere la risposta di sicuro!
Zac Taylor,

34

deleteviene utilizzato per eliminare le righe da una tabella. Dovresti usare drop tableinvece.

EXEC sp_msforeachtable 'drop table [?]'

Ciò sembrava aver risolto il problema di non avere errori, ma ora mi imbatto in errori di vincolo. La sintassi della mia NOCHECK CONSTRAINTlinea è sbagliata?
Dixuji,

1
L'ho usato su 2 tavoli veloci con FK e ha funzionato. EXEC sp_msforeachtable 'ALTER TABLE? VINCITORE DI NOCHECK all '
DaveShaw il

12
Questo ha funzionato solo per me dopo aver rimosso le parentesi quadre: EXEC sp_msforeachtable 'drop table?'.
Ottiene il

Su SQL Server sono necessarie le parentesi quadre se il nome di una tabella ha caratteri o spazi dispari. Non ho conosciuto una versione di SQL Server che non supportava le parentesi attorno ai nomi degli oggetti.
DaveShaw,

Su SQL Server 2012 (11.x) ho dovuto anche rimuovere le parentesi quadre.
Frieder,

30

La risposta accettata non supporta Azure. Utilizza una procedura memorizzata non documentata "sp_MSforeachtable". Se si verifica un errore "azzurro non è stato possibile trovare lo sp_msforeachtable della procedura memorizzata" durante l'esecuzione o si desidera semplicemente evitare di fare affidamento su funzionalità non documentate (che possono essere rimosse o modificate in qualsiasi momento), provare quanto segue.

Questa versione ignora la tabella della cronologia della migrazione del framework di entità "__MigrationHistory" e "database_firewall_rules" che è una tabella di Azure che non si dispone dell'autorizzazione per eliminare.

Leggermente testato su Azure. Verificare che ciò non abbia effetti indesiderati sul proprio 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

Preso da:

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
Ha lavorato come per magia sull'azzurro. Molto più veloce della rimozione tramite l'interfaccia utente di 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

1
Funziona in SQL Azure :) sp_MSforeachtable non funziona qui
Pavel Biryukov,

Come nota, questo fallirà se hai schemi non dbo (ad es. Se stai usando Hangfire)
Liam Dawson

21

Hai quasi ragione, usa invece:

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

ma seconda riga potrebbe essere necessario eseguire più di una volta fino a quando non si smette di ricevere errori:

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

Messaggio:

Command(s) completed successfully.

significa che tutte le tabelle sono state eliminate con successo.


17

Breve e dolce:

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
Ho dovuto sostituire sp_msforeachtablecon sp_MSforeachtablee lo consigliamo vivamente di aggiungere una use yourdatabasecome prima linea. Ha funzionato come un fascino.
Simon Sobisch,

Breve e dolce! Thnx.
sapatelbaps

7

La via del digiuno è:

  1. Nuovi diagrammi di database
  2. Aggiungi tutta la tabella
  3. Ctrl + A per selezionare tutto
  4. Fare clic destro "Rimuovi dal database"
  5. Ctrl + S per salvare
  6. Godere

Questo è di gran lunga il modo più rapido e meno soggetto a errori per farlo. Questa dovrebbe essere la risposta accettata.
SCURO Acquista il

6

Sembra che il comando dovrebbe essere senza la coperta quadrata

EXEC sp_msforeachtable 'drop table ?'

6

Per me, il modo più semplice:

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

Spot !!

È possibile utilizzare la query seguente per rimuovere tutte le tabelle dal database

EXEC sp_MSforeachtable @ command1 = "DROP TABLE?"

Buona programmazione!


1

Che ne dici di eliminare l'intero database e quindi crearlo di nuovo? Questo funziona per me.

DROP DATABASE mydb;
CREATE DATABASE mydb;

Non hai bisogno di distruggere i file mdf e ldf in mezzo?
ruffin,

Sto usando un provider di host web e non ne sono troppo sicuro. Penso che quei file verranno eliminati automaticamente quando si elimina un database, a meno che non si sia offline.
Chong Lip Phang,

2
Dipende davvero dalle circostanze. Nel mio caso, non ho stored procedure e questo metodo funziona bene per me. Non scriverò codici complessi che si estendono su dozzine di righe quando due righe lo faranno. Non credo che la mia risposta giustifichi un downvote poiché sto offrendo un suggerimento a un gruppo specifico di utenti.
Chong Lip Phang,

0

So che questo è un vecchio post ora, ma ho provato tutte le risposte qui su una moltitudine di database e ho scoperto che funzionano tutti a volte ma non tutte le volte per diverse (posso solo supporre) stranezze di SQL Server.

Alla fine ho pensato a questo. Ho testato questo ovunque (in generale) posso e funziona (senza alcuna procedura di negozio nascosta).

Da notare soprattutto su SQL Server 2014. (ma la maggior parte delle altre versioni che ho provato sembra funzionare anche bene).

Ho provato mentre loop e null ecc ecc, cursori e varie altre forme ma sembrano sempre fallire su alcuni database ma non su altri senza una ragione ovvia.

Ottenere un conteggio e usarlo per iterare sembra sempre funzionare su tutto ciò che ho testato.

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

Per le tabelle temporali è un po 'più complicato a causa del fatto che potrebbero esserci alcune chiavi esterne e anche un'eccezione:

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

Quello che puoi usare è:

-- 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.