¿Cómo soltar todas las tablas en una base de datos de SQL Server?

195

Estoy tratando de escribir un script que vacie completamente una base de datos de SQL Server. Esto es lo que tengo hasta ahora:

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

Cuando lo ejecuto en Management Studio, obtengo:

Comando (s) completado con éxito.

pero cuando actualizo la lista de la tabla, todos siguen ahí. ¿Qué estoy haciendo mal?

dixuji
fuente
Si ninguna de las soluciones en esta página está funcionando, quizás olvidó: USE [DatabaseName] GO
Serj Sagan el
2
ELIMINAR ? eliminará los registros de la tabla. Debería usar DROP TABLE ?, sin embargo, eso no funcionará por otros motivos.
datagod

Respuestas:

306

Tampoco funciona para mí cuando hay varias tablas de claves externas.
Encontré ese código que funciona y hace todo lo que intenta (elimine todas las tablas de su base de datos):

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

Puedes encontrar la publicación aquí . Es el post de Groker.

Gabriel GM
fuente
¿Por qué cuando intentas envolver todo ese bloque de código en una instrucción IF usando un bloque BEGIN-END se queja del cursor?
Adam
11
Recibo un errorCould not find stored procedure 'sp_MSForEachTable'.
Korayem
2
Esta respuesta no funciona si tiene tablas (con restricciones) en un esquema diferente que dbo. Si tiene esquemas personalizados, debe modificar el sqlpara:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg
55
sp_MSforeachtableno está disponible en Azure. Utilice la respuesta de @ CountZero en su lugar.
Ogglas
3
Encontré esta referencia en la web (no la mía): una copia del procedimiento almacenado sp_MSforeachtable para Azure, utiliza sp_MSforeach_worker: gist.github.com/metaskills/893599 .
João Vieira
330

También puede eliminar todas las tablas de la base de datos utilizando solo las herramientas de IU de MSSMS (sin utilizar el script SQL). A veces, esta forma puede ser más cómoda (especialmente si se realiza ocasionalmente)

Hago esto paso a paso de la siguiente manera:

  1. Seleccione 'Tablas' en el árbol de la base de datos (Explorador de objetos)
  2. Presione F7 para abrir la vista de detalles del Explorador de objetos
  3. En esta vista, seleccione las tablas que deben eliminarse (en este caso todas)
  4. Siga presionando Eliminar hasta que se hayan eliminado todas las tablas (lo repite tantas veces como la cantidad de errores debido a restricciones / dependencias clave)
Bronek
fuente
55
No pude obtener sp_msforeachtable para trabajar en un Azure sql db. Supongo que no lo incluyen para Azure. Esta solución funciona muy bien y es perfecta para burlarse o hacer muchos cambios (comenzar de nuevo) con migraciones EF.
trevorc
No considera FK / orden.
Josh
1
este es un método útil si solo necesita hacerlo aquí y allá, el script puede ser mejor si lo hace con frecuencia.
Dylan Hayes
2
@Josh, el orden no se considera, pero si sigue presionando Ok en el cuadro de diálogo Eliminar, seguirá eliminando todas las tablas que pueda, lo que eventualmente eliminará todas las tablas.
clayRay
Solución perfecta usando Designer
Zaheer
49

En SSMS:

  • Haga clic derecho en la base de datos
  • Ir a "Tareas"
  • Haga clic en "Generar guiones"
  • En la sección "Elegir objetos", seleccione "Script de la base de datos completa y todos los objetos de la base de datos"
  • En la sección "Establecer opciones de secuencias de comandos", haga clic en el botón "Avanzado"
  • En "Script DROP and CREATE" cambie "Script CREATE" a "Script DROP" y presione OK
  • Luego, guarde en un archivo, portapapeles o en una nueva ventana de consulta.
  • Ejecutar guión.

Ahora, esto eliminará todo, incluida la base de datos. Asegúrese de eliminar el código de los elementos que no desea que se eliminen. Alternativamente, en la sección "Elegir objetos", en lugar de seleccionar la secuencia de datos de la base de datos completa, simplemente seleccione los elementos que desea eliminar.

Ben
fuente
3
Si no desea descartar la base de datos (que en mi caso no lo hago, ya que necesitaría hacer una llamada de soporte para crearla), use 'Seleccionar objetos de base de datos específicos' y seleccione todos los tipos de objetos que Desea caer.
d219
3
Esta es la manera más fácil.
Asiri Dissanayaka
2
¡Esta debería ser la respuesta segura!
Zac Taylor
34

deletese usa para eliminar filas de una tabla. Deberías usar drop tableen su lugar.

EXEC sp_msforeachtable 'drop table [?]'
DaveShaw
fuente
Eso parecía haber solucionado el problema de no tener ningún error, pero ahora me encuentro con errores de restricción. ¿Es NOCHECK CONSTRAINTincorrecta la sintaxis de mi línea?
dixuji
1
Utilicé esto en 2 tablas rápidas con FK y funcionó. EXEC sp_msforeachtable '¿ALTERAR TABLA? NOCHECK CONSTRAINT all '
DaveShaw
12
Esto solo funcionó para mí después de eliminar los corchetes: EXEC sp_msforeachtable 'drop table?'.
LPains
En SQL Server, necesita los corchetes si algún nombre de tabla tiene caracteres o espacios extraños. No conocía una versión de SQL Server que no admitiera corchetes alrededor de los nombres de los objetos.
DaveShaw
En SQL Server 2012 (11.x) también tuve que eliminar los corchetes.
Frieder
30

La respuesta aceptada no es compatible con Azure. Utiliza un procedimiento almacenado no documentado "sp_MSforeachtable". Si obtiene un error "azure no se pudo encontrar el procedimiento almacenado 'sp_msforeachtable" cuando se ejecuta o simplemente desea evitar depender de características no documentadas (que se pueden eliminar o cambiar su funcionalidad en cualquier momento), intente lo siguiente.

Esta versión ignora la tabla del historial de migración del marco de la entidad "__MigrationHistory" y la "database_firewall_rules", que es una tabla de Azure que no tendrá permiso para eliminar.

Ligeramente probado en Azure. Verifique que esto no tenga efectos no deseados en su entorno.

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

Tomado 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
fuente
3
Funcionó como magia en azul. Mucho más rápido que eliminar a través de la interfaz de usuario de 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
fuente
1
Funciona en SQL Azure :) sp_MSforeachtable no funciona allí
Pavel Biryukov
Como nota, esto fallará si tiene esquemas no dbo (por ejemplo, si está usando Hangfire)
Liam Dawson
21

Tienes casi razón, usa en su lugar:

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

pero en la segunda línea, es posible que deba ejecutar más de una vez hasta que deje de recibir el error:

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

Mensaje:

Command(s) completed successfully.

significa que todas las tablas se eliminaron correctamente.

Michał Powaga
fuente
17

Corto y dulce:

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
fuente
2
Tuve que reemplazar sp_msforeachtablepor sp_MSforeachtabley recomendaría agregar un use yourdatabasecomo primera línea. Trabajado como un encanto.
Simon Sobisch
¡Corto y dulce! Thnx.
sapatelbaps
7

La forma en ayunas es:

  1. Nuevos diagramas de base de datos
  2. Agregar toda la tabla
  3. Ctrl + A para seleccionar todo
  4. Haga clic derecho en "Eliminar de la base de datos"
  5. Ctrl + S para guardar
  6. Disfrutar
TuanDPH
fuente
Esta es, con mucho, la forma más rápida y menos propensa a errores para hacer esto. Esta debería ser la respuesta aceptada.
DARKGuy
6

Parece que el comando debe estar sin la manta cuadrada

EXEC sp_msforeachtable 'drop table ?'
Jimmy Wong
fuente
6

Para mí, la forma más 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
fuente
2

¡¡Correcto!!

Puede usar la consulta a continuación para eliminar todas las tablas de la base de datos

EXEC sp_MSforeachtable @ command1 = "¿DROP TABLE?"

¡Feliz codificación!

Gajanan Kulkarni
fuente
1

¿Qué hay de soltar toda la base de datos y luego volver a crearla? Esto funciona para mi.

DROP DATABASE mydb;
CREATE DATABASE mydb;
Chong Lip Phang
fuente
¿No necesitas destruir los archivos mdf y ldf en el medio?
ruffin
Estoy usando un proveedor de alojamiento web y no estoy muy seguro de eso. Creo que esos archivos se eliminarán automáticamente cuando suelte una base de datos, a menos que esté fuera de línea.
Chong Lip Phang
2
Realmente depende de las circunstancias. En mi caso, no tengo procedimientos almacenados y este método funciona bien para mí. No voy a escribir códigos complejos que abarquen docenas de líneas cuando lo hagan dos líneas. No creo que mi respuesta justifique un voto negativo, ya que estoy ofreciendo una sugerencia a un grupo específico de usuarios.
Chong Lip Phang
0

Sé que esta es una publicación antigua ahora, pero he intentado todas las respuestas aquí en una multitud de bases de datos y he descubierto que todas funcionan a veces, pero no todo el tiempo, para varias peculiaridades (solo puedo asumir) de SQL Server.

Finalmente se me ocurrió esto. He probado esto en todas partes (en términos generales) que puedo y funciona (sin ningún procedimiento de almacenamiento oculto).

Para una nota principalmente en SQL Server 2014. (pero la mayoría de las otras versiones que probé también parece funcionar bien).

He intentado con bucles y nulos, etc., etc., cursores y otras formas, pero siempre parecen fallar en algunas bases de datos, pero no en otras, sin ninguna razón obvia.

Obtener un recuento y usarlo para iterar siempre parece funcionar en todo lo que he probado.

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

Para las tablas temporales es un poco más complicado debido al hecho de que puede haber algunas claves externas y también una excepción:

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

Lo que puedes usar es:

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