ลบข้อมูลทั้งหมดในฐานข้อมูล SQL Server


129

ฉันจะลบระเบียนทั้งหมดจากตารางฐานข้อมูลทั้งหมดของฉันได้อย่างไร ฉันสามารถทำได้ด้วยคำสั่ง SQL เพียงคำสั่งเดียวหรือฉันต้องการคำสั่ง SQL หนึ่งคำต่อหนึ่งตาราง

คำตอบ:


194

โซลูชันของ SQLMenace ทำงานให้ฉันด้วยการปรับแต่งเล็กน้อยเกี่ยวกับวิธีการลบข้อมูล - DELETE FROMแทนที่จะเป็น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

ฉันถึง .. ฉันสามารถลบได้ แต่ไม่ต้องตัดทอน
Marcel

17
นอกจากนี้ยังอาจเหมาะสมที่จะทำEXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'หลังจาก DELETE FROM เพื่อรีเซ็ตคอลัมน์ข้อมูลประจำตัวทั้งหมดกลับไปเป็น 0
โจนาธานแก้ไข

1
มันเป็นการเริ่มต้นวันใหม่ที่ดีเสมอเมื่อคุณพบโค้ด 6 บรรทัดที่มาแทนที่คำสั่งลบ 100s! วิธีนี้ใช้งานได้โดยไม่มีปัญหากับ SQL 2014 Express
Tommy

1
อย่าลืมปิดการใช้งานทริกเกอร์ด้วย
Edwin Stoteler

10
ผมได้รับข้อผิดพลาด DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'...- สำหรับฉันทำงาน:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

โดยปกติฉันจะใช้ sp_MSForEachTable proc ที่ไม่มีเอกสาร

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

ดูเพิ่มเติม: ลบข้อมูลทั้งหมดในฐานข้อมูล (เมื่อคุณมี FK)


1
ฉันไม่คิดว่าจะได้ผล ดูเหมือนว่า Kalen Delaney จะต้องรับผิดชอบในการเริ่มต้นแนวคิดนี้โดยไม่ได้ตั้งใจ เธอชี้แจงว่า "คุณต้องวางข้อ จำกัด ในการอ้างอิงเพื่อที่จะตัดทอนตาราง"
Martin Smith

มาร์ตินฉันเพิ่งเรียกใช้เมื่อ 2 วินาทีที่แล้วใน Adventureworks DB โดยไม่มีปัญหา
SQLMenace

มันไม่ได้ผลสำหรับฉันที่นี่แน่นอน 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
ไม่ได้ผลแม้ว่าจะถูกทำเครื่องหมายว่าเป็นคำตอบก็ตาม การตั้งค่าข้อ จำกัด nocheck บนคีย์ต่างประเทศไม่อนุญาตให้คุณรันคำสั่งตัดทอนบนตารางเหล่านั้น คุณจะยังคงได้รับข้อผิดพลาดที่ทำให้คุณไม่สามารถตัดทอนได้
4

3
ไม่สามารถใช้งานได้เนื่องจากมีคีย์แปลกปลอมอยู่ ฉันยังไม่เห็นว่าทำไมถึงได้รับคำตอบ: /
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

สคริปต์ที่น่าสนใจซึ่งไม่ได้ใช้ประโยชน์จาก proc ที่เก็บไว้ที่ไม่ได้ใส่สี 'sp_MSForEachTable' ซึ่งขาดหายไปใน Azure ต้องการการปรับแต่งหากคุณมีวัตถุในสคีมาอื่นที่ไม่ใช่ [dbo]
Pac0

โปรดใช้gist.github.com/metaskills/893599เพื่อสร้าง sp_MSForEachTable ใน Azure
Harpal

16

ฉันรู้ว่ามันสายไปแล้ว แต่ฉันเห็นด้วยกับคำแนะนำของ AlexKuznetsov ในการเขียนสคริปต์ฐานข้อมูลแทนที่จะต้องยุ่งยากกับการล้างข้อมูลออกจากตาราง หากTRUNCATEวิธีแก้ปัญหาไม่ได้ผลและคุณมีข้อมูลจำนวนมากการออกDELETEคำสั่ง(บันทึก) อาจใช้เวลานานและคุณจะเหลือตัวระบุที่ไม่ได้รับการแก้ไข (เช่นINSERTคำสั่งลงในตารางที่มีIDENTITYคอลัมน์คุณจะได้รับรหัส 50000 แทนรหัส 1)

ในการเขียนสคริปต์ฐานข้อมูลทั้งหมดใน SSMS ให้คลิกขวาที่ฐานข้อมูลจากนั้นเลือกTASKS-> Generate scripts:

ใส่คำอธิบายภาพที่นี่

คลิกNextเพื่อข้ามหน้าจอเปิดตัวช่วยสร้างจากนั้นเลือกวัตถุที่คุณต้องการใช้สคริปต์:

ใส่คำอธิบายภาพที่นี่

ในSet scripting optionsหน้าจอคุณสามารถเลือกการตั้งค่าสำหรับสคริปต์เช่นจะสร้าง 1 สคริปต์สำหรับอ็อบเจ็กต์ทั้งหมดหรือสคริปต์แยกสำหรับแต่ละอ็อบเจ็กต์และจะบันทึกไฟล์ใน Unicode หรือ ANSI:

ใส่คำอธิบายภาพที่นี่

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


โปรดระวังโดยค่าเริ่มต้นด้วยวิธีนี้คุณจะสูญเสียสิ่งต่างๆเช่นดัชนีหากคุณไม่ไปที่ปุ่ม "ขั้นสูง"
glautrou

6
  1. ก่อนอื่นคุณจะต้องปิดการใช้งานทริกเกอร์ทั้งหมด:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. เรียกใช้สคริปต์นี้: (นำมาจากโพสต์นี้ขอบคุณ @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

สคริปต์นี้จะสร้างDELETEข้อความตามลำดับที่เหมาะสม เริ่มจากตารางอ้างอิงจากนั้นอ้างอิงตาราง

  1. คัดลอกDELETE FROMคำสั่งและเรียกใช้ครั้งเดียว

  2. เปิดใช้งานทริกเกอร์

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. ยอมรับการเปลี่ยนแปลง:

    begin transaction
    commit;

สิ่งนี้ใช้ไม่ได้สำหรับฉันการสืบค้นแบบเรียกซ้ำจะจบลงแบบวนซ้ำ บางทีอาจเป็นเพราะความเคารพตัวเอง
Edwin Stoteler

5

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


3

ด้านล่างสคริปต์ที่ฉันใช้เพื่อลบข้อมูลทั้งหมดออกจากฐานข้อมูล 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

ในฐานะที่เป็นคำตอบอื่นหากคุณ Visual Studio SSDT หรือ Red Gate Sql Compare คุณสามารถเรียกใช้การเปรียบเทียบสคีมาเขียนสคริปต์ออกวางฐานข้อมูลเก่า (อาจทำการสำรองข้อมูลก่อนในกรณีที่มีเหตุผลที่คุณต้องการ ข้อมูลนั้น) จากนั้นสร้างฐานข้อมูลใหม่ด้วยสคริปต์ที่สร้างโดยเครื่องมือเปรียบเทียบ ในขณะที่ฐานข้อมูลขนาดเล็กมากอาจใช้งานได้มากกว่า แต่บนฐานข้อมูลขนาดใหญ่จะเร็วกว่ามากเพียงแค่วางฐานข้อมูลจากนั้นจัดการกับทริกเกอร์และข้อ จำกัด ต่างๆที่อาจอยู่ในฐานข้อมูล


-1

ใช่มันเป็นไปได้ที่จะลบด้วยรหัสบรรทัดเดียว

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

สิ่งนี้ทำให้ฉันได้ตารางใหม่พร้อมคำสั่งตัดทอนสำหรับแต่ละตาราง มันไม่ได้ลบอะไรเลยจริง ๆ และน่าเสียดายที่มันดูแลปัญหาการทิ้งข้อ จำกัด ก่อน น่าเสียดายที่ฉันหวังว่าจะได้รับคำตอบเช่นนั้นโดยไม่ต้องใช้ sp_MSForEachTable (ซึ่งไม่มีสำหรับฉัน Azure SQL Server)!
Pac0

ใช่. จริง มันสร้างสคริปต์ตัดทอนสำหรับตารางทั้งหมด ใช้สคริปต์นั้นเพื่อลบข้อมูลตาราง
Buddhaika De Silva

โซลูชันนี้ใช้ได้เฉพาะในกรณีที่ไม่มีความสัมพันธ์ใด ๆ เนื่องจากไม่มีทางรับประกันได้ว่าตารางจะลดลงตามลำดับที่ถูกต้อง นอกจากนี้หากมีทริกเกอร์ใด ๆ ในการลบข้อมูลสิ่งนี้อาจก่อให้เกิดผลลัพธ์ที่ไม่ได้ตั้งใจ
dmoore1181
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.