Bagaimana menghapus semua baris dari semua tabel dalam database SQL Server?

163

Bagaimana menghapus semua baris dari semua tabel dalam database SQL Server?

Michał Powaga
sumber
Lihat codeguru.com/forum/showthread.php?t=458182 dan gulir ke bawah ...
Wim ten Brink
4
oleh drop database akan dihapus saya hanya ingin me-reset data yang

Jawaban:

264

Perhatikan bahwa TRUNCATE tidak akan berfungsi jika Anda memiliki set integritas referensial.

Dalam hal ini, ini akan berhasil:

EXEC sp_MSForEachTable 'DISABLE TRIGGER ALL ON ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'DELETE FROM ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ENABLE TRIGGER ALL ON ?'
GO
Mark Rendle
sumber
1
Sebenarnya, itu hanya untuk pemicu DDL. Dalam hal ini: EXECP sp_MSForEachTable 'DISABLE TRIGGER ALL ON?'
Mark Rendle
10
Tidak tersedia di SQL Azure :(
Akash Kava
Ok saya agak bingung (mungkin Anda bisa membantu) Saya membuat cadangan dari database saya dan itu sekitar 10 MB, kemudian saya menjalankan kode SQL Anda di atas untuk mengosongkan database saya dan saya membuat cadangan baru dari apa yang saya pikir adalah database kosong untuk dikirim ke orang lain dalam email tetapi cadangan database 'kosong' saya sekarang 14 MB? Apa kesalahan yang telah aku perbuat?
Ben
1
Mengerti - jika file cadangan sudah ada maka sepertinya SSMS menambahkannya daripada menggantinya (saya tidak menyadari ini). Jadi saya menghapus file dan sekarang file cadangan database 'kosong' hanya 3,7 MB
Ben
1
Bagaimana jika saya ingin memilih DB, seperti USE [MyDataBase]:? Apakah ide di atas bekerja, jika diadaptasi entah bagaimana? ... Karena saya tidak ingin menghapus semua DB yang disimpan oleh server SQL.
סטנלי גרונן
20

Dalam proyek terbaru saya, tugas saya adalah membersihkan seluruh database dengan menggunakan pernyataan sql dan setiap tabel memiliki banyak kendala seperti Primary Key dan Foreign Key. Ada lebih dari 1000 tabel dalam basis data sehingga tidak mungkin untuk menulis kueri penghapusan pada setiap tabel.

Dengan menggunakan prosedur tersimpan bernama sp_MSForEachTable yang memungkinkan kita untuk dengan mudah memproses beberapa kode terhadap masing-masing dan setiap tabel dalam satu basis data. Ini berarti bahwa itu digunakan untuk memproses satu perintah T-SQL atau perintah T-SQL yang berbeda terhadap setiap tabel dalam database.

Jadi ikuti langkah-langkah di bawah ini untuk memotong semua tabel dalam Database SQL Server:

Langkah 1- Nonaktifkan semua kendala pada database dengan menggunakan kueri sql berikut:

EXEC sys.sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

Langkah 2- Jalankan operasi Hapus atau terpotong pada setiap tabel database dengan menggunakan perintah sql di bawah ini:

EXEC sys.sp_msforeachtable 'DELETE FROM ?'

Langkah 3- Aktifkan semua kendala pada database dengan menggunakan pernyataan sql di bawah ini:

EXEC sys.sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
e-techpulse
sumber
1
Anda cukup menjalankan langkah 2 beberapa kali sehingga pertama kali menghapus tabel dengan non dependensi, 2 kali untuk menghapus tabel tersebut gagal di pertama kali, 3 kali untuk menghapus faild di 2 kali, dll
ada ide tentang bagaimana melakukan ini sql server azure?
Zapnologica
Pendekatan ini akan bekerja juga di Azure karena hanya menggunakan SQL biasa: sqlrelease.com/delete-all-rows-from-all-tables
Jakob Lithner
15

Saya harus menghapus semua baris dan melakukannya dengan skrip berikutnya:

DECLARE @Nombre NVARCHAR(MAX);
DECLARE curso CURSOR FAST_FORWARD 
FOR 
Select Object_name(object_id) AS Nombre from sys.objects where type = 'U'

OPEN curso
FETCH NEXT FROM curso INTO @Nombre

WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
DECLARE @statement NVARCHAR(200);
SET @statement = 'DELETE FROM ' + @Nombre;
print @statement
execute sp_executesql @statement;
END
FETCH NEXT FROM curso INTO @Nombre
END
CLOSE curso
DEALLOCATE curso

Semoga ini membantu!

Gonza Oviedo
sumber
Terima kasih untuk yang satu ini, karena saya perlu mengubah pilihan untuk menghilangkan beberapa tabel. Ini berhasil dengan baik untuk itu.
Don Rolling
13

Berikut ini solusinya:

  1. Tetesan kendala (terima kasih untuk posting ini )
  2. Iterate melalui INFORMATION_SCHEMA.TABLESuntuk database tertentu
  3. SELECTS tabel berdasarkan beberapa kriteria pencarian
  4. Menghapus semua data dari tabel itu
  5. Menambahkan kembali kendala
  6. Mengizinkan mengabaikan tabel tertentu seperti sysdiagramsdan__RefactorLog

Awalnya saya mencoba EXECUTE sp_MSforeachtable 'TRUNCATE TABLE ?', tetapi itu menghapus diagram saya.

USE <DB name>;
GO

-- Disable all constraints in the database
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

declare @catalog nvarchar(250);
declare @schema nvarchar(250);
declare @tbl nvarchar(250);
DECLARE i CURSOR LOCAL FAST_FORWARD FOR select
                                        TABLE_CATALOG,
                                        TABLE_SCHEMA,
                                        TABLE_NAME
                                        from INFORMATION_SCHEMA.TABLES
                                        where
                                        TABLE_TYPE = 'BASE TABLE'
                                        AND TABLE_NAME != 'sysdiagrams'
                                        AND TABLE_NAME != '__RefactorLog'

OPEN i;
FETCH NEXT FROM i INTO @catalog, @schema, @tbl;
WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @sql NVARCHAR(MAX) = N'DELETE FROM [' + @catalog + '].[' + @schema + '].[' + @tbl + '];'
        /* Make sure these are the commands you want to execute before executing */
        PRINT 'Executing statement: ' + @sql
        -- EXECUTE sp_executesql @sql
        FETCH NEXT FROM i INTO @catalog, @schema, @tbl;
    END
CLOSE i;
DEALLOCATE i;

-- Re-enable all constraints again
EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Zach Smith
sumber
Ini bagus tetapi tidak memperhitungkan skema non-dbo.
influen
Saya tidak pernah menggunakan skema non dbo, jadi saya tidak akan menangkapnya. Tapi mengapa itu tidak berhasil? Saya tidak menentukan skema di mana pun, jadi apakah default untuk dbo saja?
Zach Smith
Jika Anda memiliki tabel, misalnya, disebut test.Table1, di mana "test" adalah skema, penghapusan Anda akan gagal jika mencoba menjalankan "DELETE FROM Table1". Itu harus HAPUS DARI tes. Tabel1.
influen
2
@influent - sekarang perlu skema non-dbo ke akun
Zach Smith
Sayangnya ini sepertinya gagal jika ada kendala FK. The ALTER TABLEbit kendala menonaktifkan gagal.
Douglas Gaskell
8

Dalam kasus saya, saya harus mengaktifkan QUOTED_IDENTIFIER pada. Ini menyebabkan sedikit modifikasi dari jawaban Mark Rendle di atas:

EXEC sp_MSForEachTable 'DISABLE TRIGGER ALL ON ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ENABLE TRIGGER ALL ON ?'
GO
William Jockusch
sumber
Bekerja untuk saya - sebelum saya mendapatkan kesalahan ini:DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
DharmaTurtle
4
Set nocount on

Exec sp_MSForEachTable 'Alter Table ? NoCheck Constraint All'

Exec sp_MSForEachTable
'
If ObjectProperty(Object_ID(''?''), ''TableHasForeignRef'')=1
Begin
-- Just to know what all table used delete syntax.
Print ''Delete from '' + ''?''
Delete From ?
End
Else
Begin
-- Just to know what all table used Truncate syntax.
Print ''Truncate Table '' + ''?''
Truncate Table ?
End
'

Exec sp_MSForEachTable 'Alter Table ? Check Constraint All'
yadavr
sumber
1

Anda bisa menghapus semua baris dari semua tabel menggunakan pendekatan seperti yang disarankan Rubens, atau Anda bisa saja menjatuhkan dan membuat ulang semua tabel. Selalu ide yang baik untuk memiliki skrip pembuatan db penuh pula sehingga mungkin merupakan metode termudah / tercepat.

AdaTheDev
sumber
tampaknya OP khawatir tentang integritas referensial dan pemicu; kasus ini, Anda punya solusi terbaik. Saya menjatuhkan jawaban saya =)
Rubens Farias
2
Maksud saya memotongnya =)
Rubens Farias
0

Untuk beberapa persyaratan, kami mungkin harus melewati tabel tertentu. Saya menulis skrip di bawah ini untuk menambahkan beberapa kondisi tambahan untuk memfilter daftar tabel. Script di bawah ini juga akan menampilkan jumlah pre delete dan post delete.

        IF OBJECT_ID('TEMPDB..#TEMPRECORDCOUNT') IS NOT NULL 
        DROP TABLE #TEMPRECORDCOUNT 

        CREATE TABLE #TEMPRECORDCOUNT 
            (    TABLENAME NVARCHAR(128)
                ,PREDELETECOUNT BIGINT
                ,POSTDELETECOUNT BIGINT
            ) 

        INSERT INTO #TEMPRECORDCOUNT (TABLENAME, PREDELETECOUNT, POSTDELETECOUNT)

        SELECT   O.name TableName
                ,DDPS.ROW_COUNT PREDELETECOUNT
                ,NULL  FROM sys.objects O 

        INNER JOIN (

                    SELECT OBJECT_ID, SUM(row_count) ROW_COUNT 
                    FROM SYS.DM_DB_PARTITION_STATS
                    GROUP BY OBJECT_ID
                   ) DDPS ON DDPS.OBJECT_ID = O.OBJECT_ID
        WHERE O.type = 'U' AND O.name NOT LIKE 'OC%' AND O.schema_id = 1

        DECLARE @TableName NVARCHAR(MAX);
        DECLARE TableDeleteCursor CURSOR FAST_FORWARD 
        FOR 
        SELECT TableName from #TEMPRECORDCOUNT

        OPEN TableDeleteCursor
        FETCH NEXT FROM TableDeleteCursor INTO @TableName

        WHILE (@@FETCH_STATUS <> -1)
        BEGIN
        IF (@@FETCH_STATUS <> -2)
        BEGIN
        DECLARE @STATEMENT NVARCHAR(MAX);
        SET @STATEMENT = ' DISABLE TRIGGER ALL ON ' + @TableName + 
                         '; ALTER TABLE ' + @TableName + ' NOCHECK CONSTRAINT ALL' +
                         '; DELETE FROM ' + @TableName +
                         '; ALTER TABLE ' + @TableName + ' CHECK CONSTRAINT ALL' +
                         '; ENABLE TRIGGER ALL ON ' + @TableName;
        PRINT @STATEMENT
        EXECUTE SP_EXECUTESQL @STATEMENT;
        END
        FETCH NEXT FROM TableDeleteCursor INTO @TableName
        END
        CLOSE TableDeleteCursor
        DEALLOCATE TableDeleteCursor

        UPDATE T 
         SET T.POSTDELETECOUNT = I.ROW_COUNT 
         FROM #TEMPRECORDCOUNT T 
         INNER JOIN (
                        SELECT O.name TableName, DDPS.ROW_COUNT ROW_COUNT  
                        FROM sys.objects O 
                        INNER JOIN (

                                SELECT OBJECT_ID, SUM(row_count) ROW_COUNT 
                                FROM SYS.DM_DB_PARTITION_STATS
                                GROUP BY OBJECT_ID
                               ) DDPS ON DDPS.OBJECT_ID = O.OBJECT_ID
                        WHERE O.type = 'U' AND O.name NOT LIKE 'OC%' AND O.schema_id = 1

                    ) I ON I.TableName COLLATE DATABASE_DEFAULT = T.TABLENAME 

        SELECT * FROM #TEMPRECORDCOUNT 
        ORDER BY TABLENAME ASC
Balasubramanian S
sumber
0

Jawaban ini didasarkan pada jawaban Zach Smith dengan mengatur ulang kolom identitas juga:

  1. Menonaktifkan semua kendala
  2. Iterasi semua tabel kecuali yang Anda pilih untuk dikecualikan
  3. Menghapus semua baris dari tabel
  4. Atur ulang kolom identitas jika ada
  5. Aktifkan kembali semua kendala

Ini pertanyaannya:

-- Disable all constraints in the database
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

declare @catalog nvarchar(250);
declare @schema nvarchar(250);
declare @tbl nvarchar(250);
DECLARE i CURSOR LOCAL FAST_FORWARD FOR select
                                        TABLE_CATALOG,
                                        TABLE_SCHEMA,
                                        TABLE_NAME
                                        from INFORMATION_SCHEMA.TABLES
                                        where
                                        TABLE_TYPE = 'BASE TABLE'
                                        AND TABLE_NAME != 'sysdiagrams'
                                        AND TABLE_NAME != '__RefactorLog'
                                        -- Optional
                                        -- AND (TABLE_SCHEMA = 'dbo')

OPEN i;
FETCH NEXT FROM i INTO @catalog, @schema, @tbl;
WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @sql NVARCHAR(MAX) = N'DELETE FROM [' + @catalog + '].[' + @schema + '].[' + @tbl + '];'
        /* Make sure these are the commands you want to execute before executing */
        PRINT 'Executing statement: ' + @sql
        --EXECUTE sp_executesql @sql

        -- Reset identity counter if one exists
        IF ((SELECT OBJECTPROPERTY( OBJECT_ID(@catalog + '.' + @schema + '.' + @tbl), 'TableHasIdentity')) = 1)
        BEGIN
            SET @sql = N'DBCC CHECKIDENT ([' + @catalog + '.' + @schema + '.' + @tbl + '], RESEED, 0)'
            PRINT 'Executing statement: ' + @sql
            --EXECUTE sp_executesql @sql
        END     

        FETCH NEXT FROM i INTO @catalog, @schema, @tbl;
    END
CLOSE i;
DEALLOCATE i;

-- Re-enable all constraints again
EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Ikan laut
sumber
Untuk satu dan lain alasan ini sebagian besar gagal karena melemparkan kesalahan kendala FK.
Douglas Gaskell
0
--Load tables to delete from
SELECT 
DISTINCT
' Delete top 1000000 from <DBName>.<schema>.' + c.TABLE_NAME + ' WHERE <Filter Clause Here>' AS query,c.TABLE_NAME AS TableName, IsDeleted=0, '<InsertSomeDescriptorHere>' AS [Source]--,t.TABLE_TYPE, c.*
            INTO dbo.AllTablesToDeleteFrom
            FROM INFORMATION_SCHEMA.TABLES AS t
            INNER JOIN information_schema.columns c ON c.TABLE_NAME = t.TABLE_NAME 
    WHERE c.COLUMN_NAME = '<column name>'
           AND c.TABLE_SCHEMA = 'dbo'
           AND c.TABLE_CATALOG = '<DB Name here>'
           AND t.TABLE_TYPE='Base table'
           --AND t.TABLE_NAME LIKE '<put filter here>'

            DECLARE @TableSelect NVARCHAR(1000)= '';
            DECLARE @Table NVARCHAR(1000)= '';
            DECLARE @IsDeleted INT= 0;
            DECLARE @NumRows INT = 1000000;
            DECLARE @Source NVARCHAR(50)='';


            WHILE ( @IsDeleted = 0 )
                BEGIN
                --This grabs one table at a time to be deleted from. @TableSelect has the sql to execute. it is important to order by IsDeleted ASC
                --because it will pull tables to delete from by those that have a 0=IsDeleted first. Once the loop grabs a table with IsDeleted=1 then this will pop out of loop

                    SELECT TOP 1
                            @TableSelect = query,
                            @IsDeleted = IsDeleted,
                            @Table = TableName,
                            @Source=[a].[Source]
                    FROM    dbo.AllTablesToDeleteFrom a
                    WHERE a.[Source]='SomeDescriptorHere'--use only if needed
                    ORDER BY a.IsDeleted ASC;--this is required because only those records returned with IsDeleted=0 will run through loop

                    --SELECT  @Table; can add this in to  monitor what table is being deleted from

                    WHILE ( @NumRows = 1000000 )--only delete a million rows at a time?

                    BEGIN 
                    EXEC sp_executesql @TableSelect;
                    SET @NumRows = @@ROWCOUNT;
                    --IF @NumRows = 1000000 --can do something here if needed
                    --One wants this loop to continue as long as a million rows is deleted. Once < 1 million rows is deleted it pops out of loop
                    --and grabs next table to delete
                    --    BEGIN
                    --SELECT  @NumRows;--can add this in to see current number of deleted records for table
                            INSERT  INTO dbo.DeleteFromAllTables
                                    ( tableName,
                                      query,
                                      cnt,
                                      [Source]
                                    )
                            SELECT  @Table,
                                    @TableSelect,
                                    @NumRows,
                                    @Source;
                     --   END; 
                END; 



SET @NumRows = 1000000;

UPDATE  a
SET     a.IsDeleted = 1
FROM    dbo.AllTablesToDeleteFrom a
WHERE   a.TableName = @Table;
--flag this as deleted so you can move on to the next table to delete from

END; 
jps
sumber
-3

jika Anda ingin menghapus seluruh tabel, Anda harus mengikuti instruksi SQL berikutnya

Delete  FROM TABLE Where PRIMARY_KEY_ is Not NULL;
laki-laki
sumber