SQL TRUNCATE数据库?如何截断所有表

问题描述 投票:28回答:10

我使用SQL Server 2008 R2。

是否有一个SQL命令清空数据库,而不必截断所有20个我的表?

我只是想删除的数据不是结构。

database sql-server-2008 truncate
10个回答
41
投票

您可以使用像这样的sp_MSforeachtable存储过程:

USE MyDatabase
EXEC sp_MSforeachtable 'TRUNCATE TABLE ?'

被警告,这将会从所有用户表中删除(通过截断)的所有数据。而如果你不能截断由于外键等,你可以运行相同的删除:

USE MyDatabase
EXEC sp_MSforeachtable 'DELETE FROM ?'

0
投票
---- Remove Constraint ----
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"

---- Delete Data ----
EXEC sp_MSForEachTable "DELETE FROM ?"

---- Add Constraint ----
EXEC sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

---- Reset Identity value ----
EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"

36
投票

我使用这个脚本

EXEC sp_MSForEachTable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL’
EXEC sp_MSForEachTable ‘DELETE FROM ?’
EXEC sp_MSForEachTable ‘ALTER TABLE ? CHECK CONSTRAINT ALL’
GO

5
投票

接受的答案完全不是那么回事,当你有外键关系。在这种情况下,你必须删除约束,并重新创建它们。下面是这样做的基础上,答案here一个存储过程

CREATE PROCEDURE [dbo].[deleteAllDataFromAllTables] AS
SET NOCOUNT ON

    DECLARE @dropAndCreateConstraintsTable TABLE ( DropStmt varchar(max) , CreateStmt varchar(max) )

    insert @dropAndCreateConstraintsTable select
      DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
          '].[' + ForeignKeys.ForeignTableName + 
          '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
    ,  CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
          '].[' + ForeignKeys.ForeignTableName + 
          '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName + 
          '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn + 
          ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
      sys.objects.[name] + ']([' +
      sys.columns.[name] + ']); '
     from sys.objects
      inner join sys.columns
        on (sys.columns.[object_id] = sys.objects.[object_id])
      inner join (
        select sys.foreign_keys.[name] as ForeignKeyName
         ,schema_name(sys.objects.schema_id) as ForeignTableSchema
         ,sys.objects.[name] as ForeignTableName
         ,sys.columns.[name]  as ForeignTableColumn
         ,sys.foreign_keys.referenced_object_id as referenced_object_id
         ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
         from sys.foreign_keys
          inner join sys.foreign_key_columns
            on (sys.foreign_key_columns.constraint_object_id
              = sys.foreign_keys.[object_id])
          inner join sys.objects
            on (sys.objects.[object_id]
              = sys.foreign_keys.parent_object_id)
            inner join sys.columns
              on (sys.columns.[object_id]
                = sys.objects.[object_id])
               and (sys.columns.column_id
                = sys.foreign_key_columns.parent_column_id)
        ) ForeignKeys
        on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
         and (ForeignKeys.referenced_column_id = sys.columns.column_id)
     where (sys.objects.[type] = 'U')
      and (sys.objects.[name] not in ('sysdiagrams'))


    DECLARE @DropStatement nvarchar(max)
    DECLARE @RecreateStatement nvarchar(max)

    DECLARE C1 CURSOR READ_ONLY
    FOR
    SELECT DropStmt from @dropAndCreateConstraintsTable
    OPEN C1

    FETCH NEXT FROM C1 INTO @DropStatement

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT 'Executing ' + @DropStatement
        execute sp_executesql @DropStatement
        FETCH NEXT FROM C1 INTO @DropStatement
    END
    CLOSE C1
    DEALLOCATE C1

    DECLARE @DeleteTableStatement nvarchar(max)
    DECLARE C2 CURSOR READ_ONLY
    FOR
    SELECT 'Delete From [dbo].[' + TABLE_NAME + ']' from INFORMATION_SCHEMA.TABLES 
        WHERE TABLE_SCHEMA = 'dbo' -- Change your schema appropriately.
    OPEN C2

    FETCH NEXT FROM C2 INTO @DeleteTableStatement

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT 'Executing ' + @DeleteTableStatement
        execute sp_executesql @DeleteTableStatement
        FETCH NEXT FROM C2 INTO  @DeleteTableStatement
    END
    CLOSE C2
    DEALLOCATE C2

    DECLARE C3 CURSOR READ_ONLY
    FOR
    SELECT CreateStmt from @dropAndCreateConstraintsTable
    OPEN C3

    FETCH NEXT FROM C3 INTO @RecreateStatement

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT 'Executing ' + @RecreateStatement
        execute sp_executesql @RecreateStatement
        FETCH NEXT FROM C3 INTO  @RecreateStatement
    END
    CLOSE C3
    DEALLOCATE C3

GO

5
投票

大多数要么提供的解决方案中不使用截形,这是从不同的DELETE,或者他们不与外键约束问题的处理。通过切塔尼亚提供的解决方案很接近,但它退到使用DELETE,它确实是在存储过程中,这似乎不符合你在哪里的摧毁数据库中的所有数据的情况。

所以,下面是我的变化,这确实使用TRUNCATE并做处理外键约束问题。

    /* TRUNCATE ALL TABLES IN A DATABASE */

DECLARE @dropAndCreateConstraintsTable TABLE
        (
         DropStmt VARCHAR(MAX)
        ,CreateStmt VARCHAR(MAX)
        )
/* Gather information to drop and then recreate the current foreign key constraints  */
INSERT  @dropAndCreateConstraintsTable
        SELECT  DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema
                + '].[' + ForeignKeys.ForeignTableName + '] DROP CONSTRAINT ['
                + ForeignKeys.ForeignKeyName + ']; '
               ,CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema
                + '].[' + ForeignKeys.ForeignTableName
                + '] WITH CHECK ADD CONSTRAINT [' + ForeignKeys.ForeignKeyName
                + '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn
                + ']) REFERENCES [' + SCHEMA_NAME(sys.objects.schema_id)
                + '].[' + sys.objects.[name] + ']([' + sys.columns.[name]
                + ']); '
        FROM    sys.objects
        INNER JOIN sys.columns
                ON ( sys.columns.[object_id] = sys.objects.[object_id] )
        INNER JOIN ( SELECT sys.foreign_keys.[name] AS ForeignKeyName
                           ,SCHEMA_NAME(sys.objects.schema_id) AS ForeignTableSchema
                           ,sys.objects.[name] AS ForeignTableName
                           ,sys.columns.[name] AS ForeignTableColumn
                           ,sys.foreign_keys.referenced_object_id AS referenced_object_id
                           ,sys.foreign_key_columns.referenced_column_id AS referenced_column_id
                     FROM   sys.foreign_keys
                     INNER JOIN sys.foreign_key_columns
                            ON ( sys.foreign_key_columns.constraint_object_id = sys.foreign_keys.[object_id] )
                     INNER JOIN sys.objects
                            ON ( sys.objects.[object_id] = sys.foreign_keys.parent_object_id )
                     INNER JOIN sys.columns
                            ON ( sys.columns.[object_id] = sys.objects.[object_id] )
                               AND ( sys.columns.column_id = sys.foreign_key_columns.parent_column_id )
                   ) ForeignKeys
                ON ( ForeignKeys.referenced_object_id = sys.objects.[object_id] )
                   AND ( ForeignKeys.referenced_column_id = sys.columns.column_id )
        WHERE   ( sys.objects.[type] = 'U' )
                AND ( sys.objects.[name] NOT IN ( 'sysdiagrams' ) )

/* SELECT * FROM @dropAndCreateConstraintsTable AS DACCT */

DECLARE @DropStatement NVARCHAR(MAX)
DECLARE @RecreateStatement NVARCHAR(MAX)

/* Drop Constraints */
DECLARE C1 CURSOR READ_ONLY
FOR
        SELECT  DropStmt
        FROM    @dropAndCreateConstraintsTable
OPEN C1

FETCH NEXT FROM C1 INTO @DropStatement

WHILE @@FETCH_STATUS = 0
      BEGIN
            PRINT 'Executing ' + @DropStatement
            EXECUTE sp_executesql @DropStatement
            FETCH NEXT FROM C1 INTO @DropStatement
      END
CLOSE C1
DEALLOCATE C1

/* Truncate all tables in the database in the dbo schema */
DECLARE @DeleteTableStatement NVARCHAR(MAX)
DECLARE C2 CURSOR READ_ONLY
FOR
        SELECT  'TRUNCATE TABLE [dbo].[' + TABLE_NAME + ']'
        FROM    INFORMATION_SCHEMA.TABLES
        WHERE   TABLE_SCHEMA = 'dbo'
                AND TABLE_TYPE = 'BASE TABLE'
  /* Change your schema appropriately if you don't want to use dbo */
OPEN C2

FETCH NEXT FROM C2 INTO @DeleteTableStatement

WHILE @@FETCH_STATUS = 0
      BEGIN
            PRINT 'Executing ' + @DeleteTableStatement
            EXECUTE sp_executesql @DeleteTableStatement
            FETCH NEXT FROM C2 INTO @DeleteTableStatement
      END
CLOSE C2
DEALLOCATE C2

/* Recreate foreign key constraints  */
DECLARE C3 CURSOR READ_ONLY
FOR
        SELECT  CreateStmt
        FROM    @dropAndCreateConstraintsTable
OPEN C3

FETCH NEXT FROM C3 INTO @RecreateStatement

WHILE @@FETCH_STATUS = 0
      BEGIN
            PRINT 'Executing ' + @RecreateStatement
            EXECUTE sp_executesql @RecreateStatement
            FETCH NEXT FROM C3 INTO @RecreateStatement
      END
CLOSE C3
DEALLOCATE C3

GO

4
投票

执行此

EXEC sp_MSforeachtable 'PRINT ''ALTER TABLE ? NOCHECK CONSTRAINT ALL'''
EXEC sp_MSforeachtable 'print ''DELETE FROM ?'''
EXEC sp_MSforeachtable 'print ''ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'''

复制后的打印结果,并将其粘贴在查询字段并执行它。它将截断所有表。


2
投票
DECLARE @nombre NVARCHAR(100)
DECLARE @tablas TABLE(nombre nvarchar(100))

INSERT INTO @tablas
SELECT t.TABLE_SCHEMA+ '.'+t.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T
DECLARE @contador INT=0

SELECT @contador=COUNT(*) FROM INFORMATION_SCHEMA.TABLES

WHILE @contador>0 
BEGIN
    SELECT TOP 1 @nombre=nombre FROM @tablas 
    DECLARE @sql NVARCHAR(500)=''
    SET @sql =@sql+'Truncate table  '+@nombre
    EXEC (@sql)
    SELECT @sql
    SET @contador=@contador-1   
    DELETE TOP (1) @tablas 
END

1
投票

以某点来自Boycs接听和mtmurdock后来的答案,我对我所有的开发或升级数据库的下列存储过程。我已经添加了一些开关,以适应自己的需求,如果我需要在语句添加到补种某些列中的数据。

(注:我会加入这个为Boycs辉煌答案评论,但我没有足够的信誉来做到这一点尚未所以,请接受我的道歉添加这是一个全新的答案。)

ALTER PROCEDURE up_ResetEntireDatabase
@IncludeIdentReseed BIT,
@IncludeDataReseed BIT
AS

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'

IF @IncludeIdentReseed = 1
BEGIN
    EXEC sp_MSForEachTable 'DBCC CHECKIDENT (''?'' , RESEED, 1)'
END

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

IF @IncludeDataReseed = 1
BEGIN
    -- Populate Core Data Table Here
END
GO

然后一旦准备好执行是非常简单的:

EXEC up_ResetEntireDatabase 1, 1

1
投票

不废话了脚本这样的:

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSforeachtable 'DBCC CHECKIDENT ( ''?'', RESEED, 0)'
GO

如果你有表的外键截断仍然无法正常工作。这个脚本会重置所有标识列也是如此。


0
投票

如果你只是想截断特定模式下的所有表也可以使用这个存储过程:

-- =============================================
-- Author:      Ben de Ridder
-- Create date: 20160513
-- Description: Truncate all tables in schema
-- =============================================
CREATE PROCEDURE TruncateAllTablesInSchema
    @schema nvarchar(50)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @table nVARCHAR(255)

    DECLARE db_cursor CURSOR FOR 
        select t.name
          from sys.tables t inner join
               sys.schemas s on 
                    t.schema_id=s.schema_id
         where s.name=@schema
         order by 1

    OPEN db_cursor   

    FETCH NEXT FROM db_cursor INTO @table   

    WHILE @@FETCH_STATUS = 0   
    BEGIN   
           declare @sql nvarchar(1000)

           set @sql = 'truncate table [' + @schema + '].[' + @table + ']'

           exec sp_sqlexec @sql

           FETCH NEXT FROM db_cursor INTO @table   
    END   

    CLOSE db_cursor   
    DEALLOCATE db_cursor 

END
GO
© www.soinside.com 2019 - 2024. All rights reserved.