SQL Server veritabanındaki tüm verileri sil


Yanıtlar:


194

SQLMenace'in çözümü, verilerin nasıl silineceğine dair küçük bir değişiklik yaparak benim için çalıştı - DELETE FROMbunun yerine 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

Me To .. Silebilirdim ama kısaltamadım.
Marcel

17
EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)'Tüm kimlik sütunlarını 0'a sıfırlamak için DELETE FROM'dan sonra bir yapmak da mantıklı olabilir.
Jonathan Amend

1
Yüzlerce silme ifadesinin yerini alan 6 satırlık kod bulduğunuzda güne her zaman iyi bir başlangıç! Bu yöntem SQL 2014 Express'te sorunsuz çalışır.
Tommy

1
Tetikleyicileri de devre dışı bırakmayı unutmayın
Edwin Stoteler

10
Hata alıyordum - DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'.... Benim için çalıştı:EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
kasi 01

36

Genellikle belgelenmemiş proc sp_MSForEachTable'ı kullanacağım

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

Ayrıca bkz: Veritabanındaki tüm verileri silin (FK'leriniz olduğunda)


1
Bunun işe yaradığını sanmıyorum. Görünüşe göre Kalen Delaney, bu fikri başlatmaktan yanlışlıkla sorumluydu. Burada, "tabloyu kısaltmak için referans sınırlamasını kaldırmanız gerektiğini" açıklıyor .
Martin Smith

Martin 2 saniye önce Adventureworks
DB'de

Burada benim için kesinlikle çalışmıyor. 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
Cevap olarak işaretlenmesine rağmen bu işe yaramıyor. Yabancı anahtarlarda nocheck kısıtlaması ayarlamak, bu tablolarda kesme komutlarını çalıştırmanıza izin vermez. Kesmenizi engelleyen hatalar almaya devam edeceksiniz.
Dördüncü

3
yabancı anahtarların varlığı nedeniyle bu çalışmaz. Yine de neden bir cevap olarak kabul edildiğini
anlayamıyorum

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

Azure'da eksik olan, belgelenmemiş depolanmış proc 'sp_MSForEachTable'ı kullanmayan ilginç betik. Yine de [dbo] dışında başka bir şemada nesneleriniz varsa ince ayar yapılması gerekir.
Pac0

Kullanın gist.github.com/metaskills/893599 Azure sp_MSForEachTable yaratmak
Harpal

16

Bunun geç olduğunun farkındayım, ancak AlexKuznetsov'un verileri tablolardan temizleme zahmetinden geçmek yerine veritabanının komut dosyası oluşturma önerisine katılıyorum. Eğer TRUNCATEçözüm değildir çalışmaları ve verilerin büyük miktarda veren var ne olacak (kayıtlı) DELETEifadeleri uzun zaman alabilir ve siz (yani bir reseeded edilmemiş tanımlayıcıları ile sol olacağım INSERTolan bir tabloya açıklama bir IDENTITYsütun size 1 ID'si yerine 50000 ID alacaktır).

Tüm bir veritabanının komut dosyasını oluşturmak için, SSMS'de veritabanına sağ tıklayın ve ardından TASKS-> öğesini seçin Generate scripts:

görüntü açıklamasını buraya girin

NextSihirbazın açılış ekranını atlamak için tıklayın ve ardından komut dosyasını yazmak istediğiniz nesneleri seçin:

görüntü açıklamasını buraya girin

Gelen Set scripting optionsekrandan, tek tek nesneler için tüm nesneleri veya ayrı komut dosyaları için 1 komut dosyası oluşturmak için ister gibi, komut dosyası ayarlarını seçebilirsiniz ve Unicode veya ANSI dosyayı kaydetmek isteyip:

görüntü açıklamasını buraya girin

Sihirbaz, her şeyin istediğiniz gibi olduğunu doğrulamak için kullanabileceğiniz ve 'Bitir'e tıklayarak kapatabileceğiniz bir özet gösterecektir.


Dikkatli olun, bu şekilde varsayılan olarak "Gelişmiş" düğmesine gitmezseniz dizinler gibi şeyleri kaybedersiniz.
glautrou

6
  1. Öncelikle tüm tetikleyicileri devre dışı bırakmanız gerekir:

    sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all';
  2. (Bu Alındığı: Bu komut dosyasını çalıştırın yazı @SQLMenace teşekkür ederiz)

    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

Bu komut dosyası, DELETEifadeleri doğru sırada üretecektir . başvurulan tablolardan başlayıp sonra bunlara başvurarak

  1. DELETE FROMİfadeleri kopyalayın ve bir kez çalıştırın

  2. tetikleyicileri etkinleştir

    sp_msforeachtable 'ALTER TABLE ? ENABLE TRIGGER all'
  3. Değişiklikleri uygulayın:

    begin transaction
    commit;

Bu benim için çalışmıyor, özyinelemeli sorgu bir döngüde sona eriyor. Belki de öz saygı yüzünden.
Edwin Stoteler

5

Veritabanındaki tüm nesnelerin komut dosyasını çıkarmak ve tabloları silmek veya kesmek için boş bir tane oluşturmak genellikle çok daha hızlıdır.


3

Bir SQL Server veritabanından tüm verileri kaldırmak için kullandığım bir komut dosyasının altında

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

Alternatif bir cevap olarak, Visual Studio SSDT veya muhtemelen Red Gate Sql Compare'i kullanıyorsanız, basitçe bir şema karşılaştırması çalıştırabilir, komut dosyasını çıkarabilir, eski veritabanını bırakabilirsiniz (muhtemelen ihtiyacınız olacak bir neden olması durumunda önce bir yedekleme yapabilirsiniz. bu veriler) ve ardından karşılaştırma aracı tarafından oluşturulan komut dosyasıyla yeni bir veritabanı oluşturun. Çok küçük bir veritabanında bu daha fazla iş olabilir, çok büyük bir veritabanında veritabanını basitçe bırakıp veritabanında olabilecek farklı tetikleyiciler ve kısıtlamalarla uğraşmak çok daha hızlı olacaktır.


-1

Evet, tek bir kod satırı ile silmek mümkündür

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

Bu bana her tablo için kesik ifadeli yeni bir tablo veriyor. Aslında hiçbir şeyi silmez ve maalesef önce kısıtlamaların kaldırılması sorunuyla ilgilenir. Çok kötü, sp_MSForEachTable kullanmadan (benim için var olmayan Azure SQL Server) böyle bir cevap bekliyordum!
Pac0

Evet. doğru. tüm tablolar için kısaltılmış komut dosyası oluşturur. Tablo verilerini silmek için bu komut dosyasını kullanın.
Buddhika De Silva

Bu çözüm, tabloların doğru sırada bırakılacağını garanti etmenin hiçbir yolu olmadığından, herhangi bir ilişkinin olmadığı durumda işe yarar. Ayrıca, verilerin silinmesiyle ilgili herhangi bir tetikleyici varsa, bu istenmeyen sonuçlar doğurabilir.
dmoore1181
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.