Hapus semua data dalam database SQL Server

129

Bagaimana saya bisa menghapus semua catatan dari semua tabel database saya? Dapatkah saya melakukannya dengan satu perintah SQL atau saya memerlukan satu perintah SQL per satu tabel?

AndreyAkinshin
sumber

Jawaban:

194

Solusi SQLMenace bekerja untuk saya dengan sedikit perubahan pada bagaimana data dihapus - DELETE FROMbukan 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
sumber
Me To .. Saya bisa menghapus, tapi tidak memotong.
Marcel
17
Mungkin juga masuk akal untuk melakukan EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'setelah DELETE FROM untuk mengatur ulang semua kolom identitas kembali ke 0.
Jonathan Amend
1
Itu selalu merupakan awal yang baik untuk hari ketika Anda menemukan 6 baris kode yang menggantikan 100-an pernyataan hapus! Metode ini bekerja tanpa masalah di SQL 2014 Express.
Tommy
1
Jangan lupa untuk menonaktifkan pemicu juga
Edwin Stoteler
10
Saya mendapatkan kesalahan - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Untuk saya bekerja:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi
36

Biasanya saya hanya akan menggunakan proc sp_MSForEachTable yang tidak berdokumen

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

Lihat juga: Hapus semua data di database (bila Anda memiliki FK)

SQLMenace
sumber
1
Saya tidak berpikir ini berhasil. Sepertinya Kalen Delaney secara tidak sengaja bertanggung jawab untuk memulai ide ini. Di sini dia menjelaskan "Anda harus menghilangkan batasan referensi untuk memotong tabel."
Martin Smith
Martin Saya baru saja menjalankannya 2 detik yang lalu di Adventureworks DB tanpa masalah
SQLMenace
Ini pasti tidak berhasil untuk saya di sini. 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
Ini tidak berhasil, meskipun telah ditandai sebagai jawabannya. Menetapkan batasan nocheck pada kunci asing tidak memungkinkan Anda menjalankan perintah truncate pada tabel tersebut. Anda masih akan mendapatkan kesalahan yang mencegah Anda melakukan pemotongan.
Keempat
3
ini tidak berfungsi karena adanya kunci asing. Masih saya tidak bisa melihat mengapa itu diterima sebagai jawaban: /
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
sumber
menarik skrip, yang tidak menggunakan proc 'sp_MSForEachTable' tersimpan yang tidak terdokumentasi, yang hilang di Azure. Perlu diubah jika Anda memiliki objek pada skema lain selain [dbo].
Pac0
Silakan gunakan gist.github.com/metaskills/893599 untuk membuat sp_MSForEachTable di Azure
Harpal
16

Saya sadar ini terlambat, tetapi saya setuju dengan saran AlexKuznetsov untuk membuat skrip database, daripada harus repot membersihkan data dari tabel. Jika TRUNCATEsolusi tidak akan berhasil, dan Anda kebetulan memiliki data dalam jumlah besar, mengeluarkan DELETEpernyataan (dicatat) mungkin membutuhkan waktu lama, dan Anda akan ditinggalkan dengan pengidentifikasi yang belum dikirim ulang (yaitu INSERTpernyataan ke dalam tabel dengan sebuah IDENTITYkolom akan membuat Anda sebuah ID 50000 bukan sebuah ID dari 1).

Untuk membuat skrip seluruh database, di SSMS, klik kanan database, lalu pilih TASKS-> Generate scripts:

masukkan deskripsi gambar di sini

Klik Nextuntuk melewati layar pembuka Wizard, lalu pilih objek mana yang ingin Anda skrip:

masukkan deskripsi gambar di sini

Di Set scripting optionslayar, Anda dapat memilih pengaturan untuk skrip, seperti apakah akan membuat 1 skrip untuk semua objek, atau skrip terpisah untuk objek individu, dan apakah akan menyimpan file di Unicode atau ANSI:

masukkan deskripsi gambar di sini

Wizard akan menampilkan ringkasan, yang dapat Anda gunakan untuk memverifikasi semuanya sesuai keinginan, dan menutupnya dengan mengklik 'Selesai'.

SchmitzIT
sumber
Hati-hati, cara ini secara default Anda akan kehilangan barang-barang seperti indeks jika Anda tidak pergi ke tombol "Advanced".
glautrou
6
  1. Pertama, Anda harus menonaktifkan semua pemicu:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. Jalankan skrip ini: (Diambil dari posting ini Terima kasih @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

Skrip ini akan menghasilkan DELETEpernyataan dalam urutan yang benar. mulai dari tabel referensi kemudian tabel referensi

  1. Salin DELETE FROMpernyataan dan jalankan sekali

  2. aktifkan pemicu

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Lakukan perubahan:

    begin transaction
    commit;
mounaim
sumber
Ini tidak berfungsi untuk saya, kueri rekursif berakhir dalam satu lingkaran. Mungkin karena rasa hormat diri.
Edwin Stoteler
5

Biasanya jauh lebih cepat untuk membuat skrip semua objek dalam database, dan membuat yang kosong, yang akan dihapus atau dipotong tabel.

AK
sumber
3

Di bawah skrip yang saya gunakan untuk menghapus semua data dari database 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
sumber
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
sumber
0

Sebagai jawaban alternatif, jika Anda Visual Studio SSDT atau mungkin Perbandingan Sql Gerbang Merah, Anda cukup menjalankan perbandingan skema, membuat skrip, melepaskan database lama (mungkin membuat cadangan terlebih dahulu jika ada alasan yang Anda perlukan data tersebut), lalu buat database baru dengan skrip yang dibuat oleh alat perbandingan. Sementara pada database yang sangat kecil ini mungkin lebih banyak pekerjaan, pada database yang sangat besar akan jauh lebih cepat untuk melepaskan database kemudian menangani berbagai pemicu dan batasan yang mungkin ada pada database.

dmoore1181
sumber
-1

Ya, dimungkinkan untuk menghapus dengan satu baris kode

SELECT 'TRUNCATE TABLE ' + d.NAME + ';' 
FROM   sys.tables d 
WHERE  type = 'U' 
Buddhika De Silva
sumber
Ini memberi saya tabel baru dengan pernyataan pemotongan untuk setiap tabel. Itu tidak benar-benar menghapus apa pun, dan sayangnya itu menangani masalah menjatuhkan kendala terlebih dahulu. Sayang sekali, saya mengharapkan jawaban seperti itu, tanpa menggunakan sp_MSForEachTable (yang tidak ada untuk saya, Azure SQL Server)!
Pac0
Iya. benar. itu buat skrip truncate untuk semua tabel. Gunakan skrip itu untuk menghapus data tabel.
Buddhika De Silva
Solusi ini hanya berfungsi jika tidak ada hubungan apa pun, karena tidak ada cara untuk menjamin bahwa tabel dijatuhkan dalam urutan yang benar. Selain itu, jika ada pemicu penghapusan data, hal ini dapat menimbulkan konsekuensi yang tidak diinginkan.
dmoore1181