จะวางตารางทั้งหมดในฐานข้อมูล SQL Server ได้อย่างไร


195

ฉันพยายามเขียนสคริปต์ที่จะทำให้ฐานข้อมูล SQL Server ว่างเปล่า นี่คือสิ่งที่ฉันมี:

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

เมื่อฉันเรียกใช้ใน Management Studio ฉันจะได้รับ:

คำสั่งเสร็จสมบูรณ์แล้ว

แต่เมื่อฉันรีเฟรชรายการตารางพวกเขาทั้งหมดยังคงอยู่ที่นั่น ผมทำอะไรผิดหรือเปล่า?


หากไม่มีวิธีแก้ไขปัญหาใด ๆ ในหน้านี้คุณอาจลืม: USE [DatabaseName] GO
Serj Sagan

2
ลบ ? จะลบบันทึกออกจากตาราง คุณควรใช้ DROP TABLE ใช่ไหม แต่นั่นไม่สามารถใช้งานได้ด้วยเหตุผลอื่น
datagod

คำตอบ:


306

มันไม่ทำงานสำหรับฉันเช่นกันเมื่อมีตารางคีย์ต่างประเทศหลายตาราง
ฉันพบว่ารหัสที่ใช้งานได้และทำทุกสิ่งที่คุณพยายาม (ลบตารางทั้งหมดออกจากฐานข้อมูลของคุณ):

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

คุณสามารถค้นหาโพสต์ที่นี่ มันคือการโพสต์โดย Groker


ทำไมเมื่อคุณพยายามที่จะหุ้มบล็อคโค้ดทั้งหมดในคำสั่ง IF โดยใช้บล็อก BEGIN-END มันจะบ่นเกี่ยวกับเคอร์เซอร์?
Adam

11
ฉันได้รับข้อผิดพลาดCould not find stored procedure 'sp_MSForEachTable'.
Korayem

2
คำตอบนี้ไม่ทำงานถ้าคุณมีตาราง (ที่มีข้อ จำกัด ) dboในสคีแตกต่างกว่า หากคุณมี schema ที่กำหนดเองคุณต้องเปลี่ยนเป็นsql:SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.CONSTRAINT_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
Asbjørn Ulsberg

5
sp_MSforeachtableไม่สามารถใช้ได้ใน Azure ใช้คำตอบของ @ CountZero แทน
Ogglas

3
พบการอ้างอิงนี้บนเว็บ (ไม่ระเบิด): สำเนา sp_MSforeachtable สำหรับขั้นตอนการเก็บสีฟ้าใช้ sp_MSforeach_worker: gist.github.com/metaskills/893599
João Vieira

333

คุณสามารถลบตารางทั้งหมดออกจากฐานข้อมูลโดยใช้เครื่องมือ MSSMS UI เท่านั้น (โดยไม่ใช้สคริปต์ SQL) บางครั้งวิธีนี้จะสะดวกสบายมากขึ้น (โดยเฉพาะหากมีการดำเนินการเป็นครั้งคราว)

ฉันทำตามขั้นตอนดังนี้:

  1. เลือก 'Tables' บนแผนผังฐานข้อมูล (Object Explorer)
  2. กด F7 เพื่อเปิดมุมมอง Object Explorer Details
  3. ในมุมมองนี้เลือกตารางที่จะต้องถูกลบ (ในกรณีนี้ทั้งหมด)
  4. กดลบต่อไปเรื่อย ๆ จนกว่าตารางทั้งหมดจะถูกลบ (คุณทำซ้ำหลาย ๆ ครั้งตามจำนวนข้อผิดพลาดเนื่องจากข้อ จำกัด ที่สำคัญ / การอ้างอิง)

5
ฉันไม่สามารถรับ sp_msforeachtable ให้ทำงานบน Azure sql db ฉันเดาว่าพวกเขาจะไม่รวมไว้ใน Azure โซลูชันนี้ใช้งานได้ดีและสมบูรณ์แบบเมื่อเยาะเย้ยหรือทำการเปลี่ยนแปลงมากมาย (เริ่มต้น) กับการย้ายถิ่นของ EF
trevorc

ไม่พิจารณาคำสั่งซื้อ FKs
Josh

1
นี่เป็นวิธีที่สะดวกถ้าคุณเพียงแค่ทำที่นี่แล้วสคริปต์อาจจะดีกว่าถ้าคุณทำบ่อยๆ
Dylan Hayes

2
@Josh จะไม่พิจารณาการสั่งซื้อ แต่ถ้าคุณกด OK ในกล่องโต้ตอบ Delete มันจะทำการลบตารางทั้งหมดที่ทำได้ซึ่งจะเป็นการลบตารางทั้งหมดในที่สุด
clayRay

โซลูชั่นที่สมบูรณ์แบบโดยใช้ Designer
Zaheer

49

ใน SSMS:

  • คลิกขวาที่ฐานข้อมูล
  • ไปที่ "Tasks"
  • คลิก "สร้างสคริปต์"
  • ในส่วน "เลือกวัตถุ" เลือก "สคริปต์ฐานข้อมูลทั้งหมดและวัตถุฐานข้อมูลทั้งหมด"
  • ในส่วน "ตั้งค่าตัวเลือกการเขียนสคริปต์" คลิกปุ่ม "ขั้นสูง"
  • ใน "Script DROP and CREATE" สลับ "Script CREATE" เป็น "Script DROP" และกดตกลง
  • จากนั้นทั้งบันทึกไปยังไฟล์คลิปบอร์ดหรือหน้าต่างแบบสอบถามใหม่
  • เรียกใช้สคริปต์

ตอนนี้สิ่งนี้จะลดลงทุกอย่างรวมถึงฐานข้อมูล ตรวจสอบให้แน่ใจว่าได้ลบรหัสสำหรับรายการที่คุณไม่ต้องการทิ้ง อีกวิธีหนึ่งในส่วน "เลือกวัตถุ" แทนที่จะเลือกสคริปต์ฐานข้อมูลทั้งหมดเพียงเลือกรายการที่คุณต้องการลบ


3
หากคุณไม่ต้องการวางฐานข้อมูล (ซึ่งในกรณีของฉันฉันไม่เป็นอย่างนั้นฉันจะต้องทำการโทรสนับสนุนเพื่อสร้างมันขึ้นมา) จากนั้นใช้ 'เลือกวัตถุฐานข้อมูลเฉพาะ' และเลือกประเภทวัตถุทั้งหมดที่ คุณต้องการที่จะลดลง
d219

3
นี่เป็นวิธีที่ง่ายที่สุด
Asiri Dissanayaka

2
นี่ควรเป็นคำตอบแน่นอน!
Zac Taylor

34

deleteใช้สำหรับลบแถวออกจากตาราง คุณควรใช้drop tableแทน

EXEC sp_msforeachtable 'drop table [?]'

ที่ดูเหมือนจะแก้ไขปัญหาของการไม่มีข้อผิดพลาด แต่ตอนนี้ฉันทำงานเป็นข้อผิดพลาดข้อ จำกัด ไวยากรณ์ของNOCHECK CONSTRAINTบรรทัดของฉันผิดหรือเปล่า?
dixuji

1
ฉันใช้สิ่งนี้กับตาราง 2 FK อย่างรวดเร็วและใช้งานได้ EXEC sp_msforeachtable 'แก้ไขตารางหรือไม่ NOCHECK CONSTRAINT all '
DaveShaw

12
สิ่งนี้ใช้ได้กับฉันหลังจากฉันลบเครื่องหมายวงเล็บเหลี่ยมแล้วเท่านั้น: EXEC sp_msforeachtable 'drop table?'
LPains

บน SQL Server คุณต้องการวงเล็บถ้าชื่อตารางใด ๆ มีอักขระแปลก ๆ หรือช่องว่าง ฉันไม่รู้จัก SQL Server รุ่นที่ไม่รองรับเครื่องหมายวงเล็บชื่อวัตถุ
DaveShaw

ใน SQL Server 2012 (11.x) ฉันต้องลบวงเล็บเหลี่ยมด้วย
Frieder

30

คำตอบที่ยอมรับไม่รองรับ Azure มันใช้กระบวนงานที่เก็บไว้ที่ไม่มีเอกสาร "sp_MSforeachtable" หากคุณได้รับข้อผิดพลาด "สีฟ้าไม่สามารถหาข้อผิดพลาด 'sp_msforeachtable" ของกระบวนงานที่เก็บไว้เมื่อรันหรือเพียงต้องการหลีกเลี่ยงการพึ่งพาคุณสมบัติที่ไม่มีเอกสาร (ซึ่งสามารถลบออกได้

รุ่นนี้ละเว้นตารางประวัติการโยกย้ายเอนทิตีของกรอบงานเอนทิตี "__MigrationHistory" และ "database_firewall_rules" ซึ่งเป็นตาราง Azure คุณจะไม่ได้รับอนุญาตให้ลบ

ทดสอบเบา ๆ บน Azure ตรวจสอบเพื่อให้สิ่งนี้ไม่มีผลกระทบที่ไม่พึงประสงค์ต่อสภาพแวดล้อม

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

เอามาจาก:

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
ทำงานเป็นเวทย์มนตร์บนฟ้า เร็วขึ้นมากแล้วนำออกผ่าน UI ของ 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
ทำงานใน SQL Azure :) sp_MSforeachtable ไม่ทำงานที่นั่น
Pavel Biryukov

โปรดทราบว่าสิ่งนี้จะล้มเหลวหากคุณมี schema ที่ไม่ใช่ dbo (เช่นหากคุณกำลังใช้ Hangfire)
Liam Dawson

21

คุณเกือบถูกต้องใช้แทน:

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

แต่บรรทัดที่สองคุณอาจต้องดำเนินการมากกว่าหนึ่งครั้งจนกว่าคุณจะหยุดรับข้อผิดพลาด:

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

ข้อความ:

Command(s) completed successfully.

หมายความว่าตารางทั้งหมดถูกลบเรียบร้อยแล้ว


17

สั้นและหวาน:

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
ฉันต้องแทนที่sp_msforeachtableด้วยsp_MSforeachtableและขอแนะนำให้เพิ่มuse yourdatabaseบรรทัดแรก ทำงานเหมือนจับใจ
Simon Sobisch

สั้นและหวาน! ขอบคุณ
sapatelbaps

7

วิธีการอดอาหารคือ:

  1. ใหม่ฐานข้อมูลไดอะแกรม
  2. เพิ่มตารางทั้งหมด
  3. Ctrl + A เพื่อเลือกทั้งหมด
  4. คลิกขวาที่ "ลบออกจากฐานข้อมูล"
  5. Ctrl + S เพื่อบันทึก
  6. สนุก

นี่เป็นวิธีที่เร็วที่สุดและผิดพลาดน้อยที่สุดในการทำเช่นนี้ นี่ควรเป็นคำตอบที่ยอมรับได้
DARKGuy


6

สำหรับฉันวิธีที่ง่ายที่สุด:

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

จับได้เห็นชัดตรงเผง!!

คุณสามารถใช้แบบสอบถามด้านล่างเพื่อลบตารางทั้งหมดออกจากฐานข้อมูล

EXEC sp_MSforeachtable @ command1 = "ตาราง DROP?"

การเข้ารหัสมีความสุข!


1

วิธีการเกี่ยวกับการลดฐานข้อมูลทั้งหมดแล้วสร้างอีกครั้ง มันใช้งานได้สำหรับฉัน

DROP DATABASE mydb;
CREATE DATABASE mydb;

คุณไม่จำเป็นต้องทำลายไฟล์ mdf & ldf หรือ?
ruffin

ฉันใช้ผู้ให้บริการโฮสต์เว็บและฉันก็ไม่แน่ใจเหมือนกัน ฉันคิดว่าไฟล์เหล่านั้นจะถูกลบโดยอัตโนมัติเมื่อคุณวางฐานข้อมูลเว้นแต่ว่าคุณจะออฟไลน์
Chong Lip Phang

2
มันขึ้นอยู่กับสถานการณ์ ในกรณีของฉันฉันไม่มีขั้นตอนการจัดเก็บและวิธีนี้ใช้ได้ดีสำหรับฉัน ฉันจะไม่เขียนโค้ดที่ซับซ้อนที่ครอบคลุมหลายสิบบรรทัดเมื่อสองบรรทัดจะทำ ฉันไม่คิดว่าคำตอบของฉันจะแสดงให้เห็นถึง downvote เนื่องจากฉันกำลังเสนอข้อเสนอแนะให้กับกลุ่มผู้ใช้ที่เฉพาะเจาะจง
ปากช่องปากพัง

0

ฉันรู้ว่านี่เป็นโพสต์เก่าตอนนี้ แต่ฉันได้ลองคำตอบทั้งหมดที่นี่ในฐานข้อมูลที่หลากหลายและฉันได้พบพวกเขาทั้งหมดทำงานบางครั้ง แต่ไม่ตลอดเวลาสำหรับ quirks ต่างๆของ SQL Server (ฉันเท่านั้นที่สามารถสันนิษฐานได้)

ในที่สุดฉันก็มากับสิ่งนี้ ฉันได้ทดสอบสิ่งนี้ทุกที่ (พูดโดยทั่วไป) ฉันทำได้และใช้งานได้ (ไม่มีขั้นตอนการจัดเก็บที่ซ่อนอยู่)

สำหรับโน้ตส่วนใหญ่ใน SQL Server 2014 (แต่เวอร์ชันอื่น ๆ ส่วนใหญ่ที่ฉันลองมันก็ดูเหมือนว่าจะทำงานได้ดี)

ฉันได้ลองในขณะที่ลูปและโมฆะ ฯลฯ ฯลฯ เคอร์เซอร์และรูปแบบอื่น ๆ แต่พวกเขาดูเหมือนจะล้มเหลวในฐานข้อมูลบางอย่าง แต่ไม่ใช่คนอื่น ๆ ด้วยเหตุผลไม่ชัดเจน

การนับและใช้สิ่งนั้นซ้ำ ๆ ดูเหมือนว่าจะทำงานกับทุกสิ่งที่ฉันทดสอบ

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

สำหรับตารางชั่วคราวมันซับซ้อนกว่านี้เล็กน้อยเนื่องจากอาจมีคีย์ต่างประเทศบางตัวและมีข้อยกเว้น:

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

สิ่งที่คุณสามารถใช้คือ:

-- 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.