Xóa tất cả dữ liệu trong cơ sở dữ liệu SQL Server


129

Làm thế nào tôi có thể xóa tất cả các bản ghi từ tất cả các bảng của cơ sở dữ liệu của tôi? Tôi có thể làm điều đó với một lệnh SQL hoặc tôi cần một lệnh SQL cho mỗi bảng không?

Câu trả lời:


194

Giải pháp của SQLMenace đã làm việc với tôi với một chút tinh chỉnh về cách xóa dữ liệu - DELETE FROMthay vì 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

Tôi To .. Tôi đã có thể xóa, nhưng không thể cắt ngắn.
Marcel

17
Cũng có thể có ý nghĩa để thực hiện EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'sau khi XÓA TỪ để đặt lại tất cả các cột danh tính trở về 0.
Jonathan Amend

1
Nó luôn luôn là một khởi đầu tốt cho ngày hôm nay khi bạn tìm thấy 6 dòng mã thay thế cho 100 câu lệnh xóa! Phương pháp này hoạt động mà không có vấn đề trên SQL 2014 Express.
Tommy

1
Đừng quên tắt các kích hoạt cũng như
Edwin Stoteler

10
Tôi đã nhận được lỗi - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Đối với tôi đã làm việc:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi

36

Thông thường tôi sẽ chỉ sử dụng Proc sp_MSForEachTable không có giấy tờ

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

Xem thêm: Xóa tất cả dữ liệu trong cơ sở dữ liệu (khi bạn có FK)


1
Tôi không nghĩ rằng nó hoạt động. Có vẻ như Kalen Delaney đã vô tình chịu trách nhiệm cho việc bắt đầu ý tưởng này. Ở đây cô ấy làm rõ "bạn phải bỏ các ràng buộc tham chiếu để cắt bớt bảng."
Martin Smith

Martin Tôi mới chạy nó 2 giây trước trong DB Adventureworks mà không gặp vấn đề gì
SQLMenace

Nó chắc chắn không làm việc cho tôi ở đây. 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
Điều này không hoạt động, mặc dù được đánh dấu là câu trả lời. Đặt ràng buộc nocheck trên các khóa ngoại không cho phép bạn chạy các lệnh cắt ngắn trên các bảng đó. Bạn vẫn sẽ nhận được các lỗi ngăn bạn cắt ngắn.
Thứ tư

3
Điều này không hoạt động do sự hiện diện của khóa ngoại. Tuy nhiên, tôi không thể hiểu tại sao nó được chấp nhận như một câu trả lời: /
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

tập lệnh thú vị, không sử dụng gói 'sp_MSForEachTable' được lưu trữ chưa phân tách, bị thiếu trên Azure. Cần điều chỉnh nếu bạn có các đối tượng trên một lược đồ khác ngoài [dbo].
Pac0

Vui lòng sử dụng gist.github.com/metaskills/893599 để tạo sp_MSForEachTable trong Azure
Harpal

16

Tôi biết điều này là muộn, nhưng tôi đồng ý với đề xuất của AlexKuznetsov về kịch bản cơ sở dữ liệu, thay vì phải trải qua những rắc rối trong việc xóa dữ liệu từ các bảng. Nếu TRUNCATEgiải pháp không hoạt động và bạn có một lượng lớn dữ liệu, việc phát hành (đã ghi) DELETEcó thể mất nhiều thời gian và bạn sẽ bị bỏ lại với các mã định danh chưa được xác định lại (ví dụ: một INSERTcâu lệnh vào bảng một IDENTITYcột sẽ giúp bạn có ID là 50000 thay vì ID là 1).

Để kịch bản toàn bộ cơ sở dữ liệu, trong SSMS, nhấp chuột phải vào cơ sở dữ liệu, sau đó chọn TASKS-> Generate scripts:

nhập mô tả hình ảnh ở đây

Bấm Nextđể bỏ qua màn hình mở Wizard, rồi chọn đối tượng bạn muốn script:

nhập mô tả hình ảnh ở đây

Trong Set scripting optionsmàn hình, bạn có thể chọn cài đặt cho tập lệnh, như có tạo 1 tập lệnh cho tất cả các đối tượng hay tách tập lệnh cho từng đối tượng riêng lẻ hay không và lưu tập tin bằng Unicode hoặc ANSI:

nhập mô tả hình ảnh ở đây

Trình hướng dẫn sẽ hiển thị một bản tóm tắt mà bạn có thể sử dụng để xác minh mọi thứ như mong muốn và đóng bằng cách nhấp vào 'Hoàn tất'.


Hãy cẩn thận, theo cách này theo mặc định, bạn sẽ mất các thứ như chỉ mục nếu bạn không đi tới nút "Nâng cao".
glautrou

6
  1. Trước tiên, bạn sẽ phải tắt tất cả các kích hoạt:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Chạy tập lệnh này: (Lấy từ bài đăng này Cảm ơn bạn @QueryMenace)

    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
    

Kịch bản này sẽ tạo ra các DELETEbáo cáo theo đúng thứ tự. bắt đầu từ các bảng được tham chiếu rồi tham chiếu các bảng

  1. Sao chép các DELETE FROMcâu lệnh và chạy chúng một lần

  2. kích hoạt

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Cam kết thay đổi:

    begin transaction
    commit;
    

Điều này không làm việc cho tôi, truy vấn đệ quy kết thúc trong một vòng lặp. Có lẽ vì tự tôn.
Edwin Stoteler

5

Nó thường nhanh hơn nhiều để kịch bản ra tất cả các đối tượng trong cơ sở dữ liệu và tạo một đối tượng trống để xóa khỏi hoặc cắt bớt các bảng.


3

Bên dưới tập lệnh mà tôi đã sử dụng để xóa tất cả dữ liệu khỏi cơ sở dữ liệu 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

Như một câu trả lời khác, nếu bạn so sánh Visual Studio SSDT hoặc có thể là Red Gate Sql So sánh, bạn có thể chỉ cần chạy một so sánh lược đồ, kịch bản ra, bỏ cơ sở dữ liệu cũ (có thể tạo bản sao lưu trước trong trường hợp bạn cần dữ liệu đó), và sau đó tạo một cơ sở dữ liệu mới với tập lệnh được tạo bởi công cụ so sánh. Mặc dù trên một cơ sở dữ liệu rất nhỏ, điều này có thể làm việc nhiều hơn, nhưng trên một cơ sở dữ liệu rất lớn, việc bỏ cơ sở dữ liệu sau đó để xử lý các ràng buộc và ràng buộc khác nhau có thể có trên cơ sở dữ liệu sẽ nhanh hơn nhiều.


-1

Có, có thể xóa bằng một dòng mã

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

Điều này mang lại cho tôi một bảng mới với một tuyên bố cắt ngắn cho mỗi bảng. Nó không thực sự xóa bất cứ điều gì, và thật không may, nó quan tâm đến vấn đề bỏ các ràng buộc đầu tiên. Thật tệ, tôi đã hy vọng có một câu trả lời như vậy, mà không sử dụng sp_MSForEachTable (không tồn tại đối với tôi, Azure SQL Server)!
Pac0

Đúng. thật. nó tạo tập lệnh cắt ngắn cho tất cả các bảng. Sử dụng tập lệnh đó để xóa dữ liệu bảng.
Buddhaika De Silva

Giải pháp này chỉ hoạt động trong trường hợp không có bất kỳ mối quan hệ nào, vì nó không có cách nào đảm bảo rằng các bảng được loại bỏ theo đúng thứ tự. Ngoài ra, nếu có bất kỳ tác nhân nào trong việc xóa dữ liệu, điều này có thể gây ra hậu quả không lường trước được.
dmoore1181
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.