Eliminar todos los datos en la base de datos de SQL Server

Respuestas:

194

La solución de SQLMenace funcionó para mí con un ligero ajuste en cómo se eliminan los datos, en DELETE FROMlugar de hacerlo 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
Ryan Kirkman
fuente
Yo a ... Pude eliminar, pero no truncar.
Marcel
17
También podría tener sentido hacer un EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'después de DELETE FROM para restablecer todas las columnas de identidad a 0.
Jonathan Enmiende el
1
¡Siempre es un buen comienzo para el día cuando encuentra 6 líneas de código que reemplazan cientos de declaraciones de eliminación! Este método funciona sin problemas en SQL 2014 Express.
Tommy
1
No olvides desactivar los disparadores también
Edwin Stoteler
10
Estaba recibiendo un error - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Para mí trabajó:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi
36

Por lo general, solo usaré el proceso indocumentado 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 también: Eliminar todos los datos en la base de datos (cuando tiene FK)

SQLMenace
fuente
1
No creo que esto funcione. Parece que Kalen Delaney fue inadvertidamente responsable de comenzar esta idea. Aquí ella aclara "hay que eliminar la restricción de referencia para truncar la tabla".
Martin Smith
Martin, lo ejecuté hace 2 segundos en Adventureworks DB sin ningún problema
SQLMenace
Definitivamente no funciona para mí aquí. 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
Esto no funciona, a pesar de estar marcado como la respuesta. Establecer la restricción de nocheck en claves foráneas no le permite ejecutar comandos truncados en esas tablas. Seguirá recibiendo errores que le impiden truncar.
Cuarto
3
Esto no funciona debido a la presencia de claves foráneas. Todavía no puedo ver por qué fue aceptado como respuesta: /
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
Harpal
fuente
secuencia de comandos interesante, que no utiliza el proceso almacenado no activado 'sp_MSForEachTable', que falta en Azure. Sin embargo, necesita ajustes si tiene objetos en otro esquema que no sea [dbo].
Pac0
Utilice gist.github.com/metaskills/893599 para crear sp_MSForEachTable en Azure
Harpal el
16

Sé que es tarde, pero estoy de acuerdo con la sugerencia de AlexKuznetsov de crear un script para la base de datos, en lugar de pasar por la molestia de purgar los datos de las tablas. Si la TRUNCATEsolución no funciona y resulta que tiene una gran cantidad de datos, la emisión de DELETEdeclaraciones (registradas) puede llevar mucho tiempo, y quedará con identificadores que no se han reiniciado (es decir, una INSERTdeclaración en una tabla con unIDENTITY columna le daría una identificación de 50000 en lugar de una identificación de 1).

Para crear una secuencia de comandos de una base de datos completa, en SSMS, haga clic con el botón derecho en la base de datos, luego seleccione TASKS-> Generate scripts:

ingrese la descripción de la imagen aquí

Haga clic Nextpara omitir la pantalla de apertura del Asistente y luego seleccione qué objetos desea escribir:

ingrese la descripción de la imagen aquí

En la Set scripting optionspantalla, puede elegir la configuración de las secuencias de comandos, como generar 1 secuencia de comandos para todos los objetos, o secuencias de comandos separadas para los objetos individuales, y si guardar el archivo en Unicode o ANSI:

ingrese la descripción de la imagen aquí

El asistente mostrará un resumen, que puede usar para verificar que todo esté como lo desea, y cerrar haciendo clic en 'Finalizar'.

SchmitzIT
fuente
Tenga cuidado, de esta manera por defecto perderá cosas como índices si no va al botón "Avanzado".
glautrou
6
  1. Primero tendrás que deshabilitar todos los disparadores:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Ejecute este script: (Tomado de esta publicación Gracias @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 producirá DELETEdeclaraciones en el orden correcto. a partir de tablas referenciadas y luego haciendo referencia a las

  1. Copie las DELETE FROMdeclaraciones y ejecútelas una vez

  2. habilitar disparadores

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Cometer los cambios:

    begin transaction
    commit;
mounaim
fuente
Esto no funciona para mí, la consulta recursiva termina en un bucle. Quizás por auto reverencia.
Edwin Stoteler
5

Por lo general, es mucho más rápido escribir todos los objetos en la base de datos y crear uno vacío, que eliminar o truncar tablas.

Alaska
fuente
3

Debajo de un script que usé para eliminar todos los datos de una base de datos de 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
-- ....
-- ....
-- ....
benahm
fuente
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
mikem
fuente
0

Como respuesta alternativa, si visualiza SSDT de Visual Studio o posiblemente Red Gate Sql Compare, simplemente puede ejecutar una comparación de esquemas, escribir un script, descartar la base de datos anterior (posiblemente hacer una copia de seguridad primero en caso de que haya una razón por la que necesitará esos datos) y luego cree una nueva base de datos con el script creado por la herramienta de comparación. Mientras que en una base de datos muy pequeña esto puede ser más trabajo, en una base de datos muy grande será mucho más rápido simplemente soltar la base de datos y luego lidiar con los diferentes desencadenantes y restricciones que pueden estar en la base de datos.

dmoore1181
fuente
-1

Sí, es posible eliminar con una sola línea de código.

SELECT 'TRUNCATE TABLE ' + d.NAME + ';' 
FROM   sys.tables d 
WHERE  type = 'U' 
Buddhika De Silva
fuente
Esto me da una nueva tabla con una declaración truncada para cada tabla. En realidad, no elimina nada, y desafortunadamente se ocupa primero del problema de eliminar las restricciones. ¡Qué pena, esperaba una respuesta como esa, sin el uso de sp_MSForEachTable (que no existe para mí, Azure SQL Server)!
Pac0
si. cierto. es crear script truncado para todas las tablas. Use esa secuencia de comandos para eliminar datos de tablas.
Buddhika De Silva
Esta solución solo funciona en el caso de que no haya ninguna relación, ya que no tiene forma de garantizar que las tablas se eliminen en el orden correcto. Además, si hay algún desencadenante en la eliminación de datos, esto podría tener consecuencias no deseadas.
dmoore1181