Elimina tutti i dati nel database di SQL Server


Risposte:


194

La soluzione di SQLMenace ha funzionato per me con una leggera modifica della modalità di eliminazione dei dati, DELETE FROManziché 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 .. Sono stato in grado di eliminare, ma non di troncare.
Marcel,

17
Potrebbe anche avere senso fare un EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'dopo il DELETE FROM per riportare tutte le colonne di identità su 0.
Jonathan Amend

1
È sempre un buon inizio per il giorno in cui trovi 6 righe di codice che sostituiscono centinaia di istruzioni di eliminazione! Questo metodo funziona senza problemi su SQL 2014 Express.
Tommy

1
Non dimenticare di disabilitare anche i trigger
Edwin Stoteler,

10
Stavo ricevendo un errore - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Per me ha funzionato:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Di solito userò solo proc sp_MSForEachTable senza documenti

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

Vedi anche: Elimina tutti i dati nel database (quando hai FK)


1
Non penso che funzioni. Sembra che Kalen Delaney sia stato inavvertitamente responsabile dell'avvio di questa idea. Qui chiarisce "devi eliminare il vincolo di riferimento per troncare la tabella".
Martin Smith,

Martin L'ho appena eseguito 2 secondi fa nel DB Adventureworks senza problemi
SQLMenace

Sicuramente non funziona per me qui. 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
Questo non funziona, nonostante sia contrassegnato come risposta. L'impostazione del vincolo Nocheck su chiavi esterne non consente di eseguire comandi di troncamento su tali tabelle. Riceverai comunque errori che ti impediscono di troncare.
Quarto

3
questo non funziona a causa della presenza di chiavi esterne. Non riesco ancora a capire perché sia ​​stato accettato come risposta: /
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

script interessante, che non utilizza il proc memorizzato non documentato "sp_MSForEachTable", che manca in Azure. Tuttavia, è necessario modificare se si dispone di oggetti su un altro schema diverso da [dbo].
Pac0

Utilizzare gist.github.com/metaskills/893599 per creare sp_MSForEachTable in Azure
Harpal,

16

Sono consapevole che questo è in ritardo, ma sono d'accordo con il suggerimento di AlexKuznetsov di scrivere il database, piuttosto che passare attraverso la seccatura di eliminare i dati dalle tabelle. Se la TRUNCATEsoluzione non funziona e ti capita di avere una grande quantità di dati, l'emissione di DELETEistruzioni (registrate) potrebbe richiedere molto tempo e ti rimarranno degli identificativi che non sono stati sottoposti a reseing (ovvero INSERTun'istruzione in una tabella con una IDENTITYcolonna ti darà un ID di 50000 invece di un ID di 1).

Per eseguire lo script di un intero database, in SSMS, fare clic con il pulsante destro del mouse sul database, quindi selezionare TASKS-> Generate scripts:

inserisci qui la descrizione dell'immagine

Fare clic Nextper saltare la schermata di apertura della procedura guidata, quindi selezionare quali oggetti si desidera script:

inserisci qui la descrizione dell'immagine

Nella Set scripting optionsschermata, puoi scegliere le impostazioni per gli script, ad esempio se generare 1 script per tutti gli oggetti o script separati per i singoli oggetti e se salvare il file in Unicode o ANSI:

inserisci qui la descrizione dell'immagine

La procedura guidata mostrerà un riepilogo, che è possibile utilizzare per verificare che tutto sia come desiderato e chiudere facendo clic su "Fine".


Fai attenzione, in questo modo per impostazione predefinita perderai cose come gli indici se non vai al pulsante "Avanzate".
Glautrou,

6
  1. Innanzitutto dovrai disabilitare tutti i trigger:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Esegui questo script: (Tratto da questo post Grazie @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
    

Questo script produrrà le DELETEdichiarazioni nell'ordine corretto. partendo da tabelle referenziate e poi referenziando quelle

  1. Copia le DELETE FROMdichiarazioni ed eseguile una volta

  2. abilitare i trigger

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Conferma le modifiche:

    begin transaction
    commit;
    

Questo non funziona per me, la query ricorsiva finisce in un ciclo. Forse a causa delle riverenze di sé.
Edwin Stoteler,

5

Di solito è molto più veloce eseguire lo script di tutti gli oggetti nel database e crearne uno vuoto, che consente di eliminare o troncare le tabelle.


3

Di seguito uno script che ho usato per rimuovere tutti i dati da un database di 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

Come risposta alternativa, se Visual Studio SSDT o eventualmente Red Gate Sql Compare, potresti semplicemente eseguire un confronto dello schema, copiarlo, eliminare il vecchio database (eventualmente fare prima un backup nel caso in cui ci fosse un motivo che ti servirà quei dati), quindi creare un nuovo database con lo script creato dallo strumento di confronto. Mentre su un database molto piccolo questo può richiedere più lavoro, su un database molto grande sarà molto più veloce semplicemente rilasciare il database, quindi gestire i diversi trigger e vincoli che potrebbero essere presenti nel database.


-1

Sì, è possibile eliminare con una singola riga di codice

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

Questo mi dà una nuova tabella con un'istruzione troncata per ogni tabella. In realtà non elimina nulla e purtroppo si occupa innanzitutto del problema di eliminare i vincoli. Peccato, speravo in una risposta del genere, senza l'uso di sp_MSForEachTable (che non esiste per me, Azure SQL Server)!
Pac0

sì. vero. crea lo script troncato per tutte le tabelle. Utilizzare quello script per eliminare i dati delle tabelle.
Buddhika De Silva,

Questa soluzione funziona solo nel caso in cui non vi siano relazioni, in quanto non ha modo di garantire che le tabelle vengano eliminate nell'ordine corretto. Inoltre, se vi sono trigger sulla cancellazione dei dati, ciò potrebbe comportare conseguenze indesiderate.
dmoore1181,
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.