当前位置: 代码迷 >> SQL >> MSSQL中怎么用SQL清除所有表的数据(downmoon)
  详细解决方案

MSSQL中怎么用SQL清除所有表的数据(downmoon)

热度:36   发布时间:2016-05-05 13:31:01.0
MSSQL中如何用SQL清除所有表的数据(downmoon)?
有朋友问起:MSSQL中如何用SQL清除所有表的数据?这个需求分三种类型:
第一:只要数据库中表是空的;
第二:表是空的,并且自增长列可以从1开始增长。
第三:表是空的,并且自增长列可以从1开始增长,而且存在表间的约束。
邀月稍微整理了下,放在这里,便于有需要的朋友参阅。
其实,这不算什么需求。只要用数据库的生成脚本,几分钟即可生成一个干净的表结构及存储过程、视图、约束等。这里提供了另一种用SQL解决问题的方案。权当是无聊的学习,加深点印象吧。呵呵。
首先,作一些假设:假设database名为TestDB_2000_2005_2008
预先准备一些脚本

view plaincopy to clipboardprint?

   1. use master 
   2. go 
   3. IF OBJECT_ID('TestDB_2000_2005_2008') IS NOT NULL 
   4. -- print 'Exist databse!' 
   5. -- else print 'OK!' 
   6. DROP Database TestDB_2000_2005_2008 
   7. GO 
   8. Create database TestDB_2000_2005_2008 
   9. go 
  10. use TestDB_2000_2005_2008 
  11. go 
  12. IF OBJECT_ID('b') IS NOT NULL 
  13. drop table b  
  14. go 
  15. create table b(id int identity(1,1),ba int,bb int) 
  16. --truncate table b  
  17. insert into b  
  18. select  1,1 union all 
  19. select 2,2 union all 
  20. select 1,1 
  21. IF OBJECT_ID('c') IS NOT NULL 
  22. drop table c 
  23. go 
  24. create table c(id int identity(1,1),ca int,cb int) 
  25. insert into c  
  26. select  1,2 union all 
  27. select 1,3 

use master go IF OBJECT_ID('TestDB_2000_2005_2008') IS NOT NULL -- print 'Exist databse!' -- else print 'OK!' DROP Database TestDB_2000_2005_2008 GO Create database TestDB_2000_2005_2008 go use TestDB_2000_2005_2008 go IF OBJECT_ID('b') IS NOT NULL drop table b go create table b(id int identity(1,1),ba int,bb int) --truncate table b insert into b select 1,1 union all select 2,2 union all select 1,1 IF OBJECT_ID('c') IS NOT NULL drop table c go create table c(id int identity(1,1),ca int,cb int) insert into c select 1,2 union all select 1,3

先来看看第一种需求: 只要数据库中表是空的。
这个其实并不难,用一个游标循环得出所有表名,再清除所有表,delete或truncate table
提供几个语句:以下语句均在SQL2000/SQL2005/SQL2008下使用通过。

方法甲:

+ expand sourceview plaincopy to clipboardprint?

   1. /********************MSSQL 2000/2005/2008***********************/ 
   2. use TestDB_2000_2005_2008 
   3. go 
   4. select * from b  
   5. select * from c  
   6. Declare @t varchar (1024) 
   7. Declare @SQL varchar(2048) 
   8. Declare tbl_cur cursor for  select TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' 
   9. OPEN tbl_cur FETCH NEXT  from tbl_cur INTO @t 
  10. WHILE @@FETCH_STATUS = 0 
  11. BEGIN 
  12. SET @SQL='TRUNCATE TABLE '+ @t 
  13. --print (@SQL) 
  14. EXEC (@SQL) 
  15. FETCH NEXT  from tbl_cur INTO @t 
  16. END 
  17. CLOSE tbl_cur 
  18. DEALLOCATE tbl_Cur 
  19. select * from b  
  20. select * from c  

/********************MSSQL 2000/2005/2008***********************/ use TestDB_2000_2005_2008 go select * from b select * from c Declare @t varchar (1024) Declare @SQL varchar(2048) Declare tbl_cur cursor for select TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' OPEN tbl_cur FETCH NEXT from tbl_cur INTO @t WHILE @@FETCH_STATUS = 0 BEGIN SET @SQL='TRUNCATE TABLE '+ @t --print (@SQL) EXEC (@SQL) FETCH NEXT from tbl_cur INTO @t END CLOSE tbl_cur DEALLOCATE tbl_Cur select * from b select * from c

方法乙:

+ expand sourceview plaincopy to clipboardprint?

   1. /********************MSSQL 2000/2005/2008***********************/ 
   2. use TestDB_2000_2005_2008 
   3. go 
   4. select * from b  
   5. select * from c  
   6. select * from d  
   7. select * from e  
   8. DECLARE @TableName VARCHAR(256) 
   9. DECLARE @varSQL VARCHAR(512) 
  10. DECLARE @getTBName CURSOR SET @getTBName = CURSOR FOR SELECT name FROM sys.Tables WHERE NAME NOT LIKE 'Category' 
  11. OPEN @getTBName FETCH NEXT FROM @getTBName INTO @TableName 
  12. WHILE @@FETCH_STATUS = 0 
  13. BEGIN 
  14. SET @varSQL = 'Truncate table '+ @TableName  
  15. --PRINT (@varSQL) 
  16. EXEC (@varSQL) 
  17. FETCH NEXT FROM @getTBName INTO @TableName 
  18. END 
  19. CLOSE @getTBName 
  20. DEALLOCATE @getTBName 
  21. ----select * from b  
  22. ----select * from c 

/********************MSSQL 2000/2005/2008***********************/ use TestDB_2000_2005_2008 go select * from b select * from c select * from d select * from e DECLARE @TableName VARCHAR(256) DECLARE @varSQL VARCHAR(512) DECLARE @getTBName CURSOR SET @getTBName = CURSOR FOR SELECT name FROM sys.Tables WHERE NAME NOT LIKE 'Category' OPEN @getTBName FETCH NEXT FROM @getTBName INTO @TableName WHILE @@FETCH_STATUS = 0 BEGIN SET @varSQL = 'Truncate table '+ @TableName --PRINT (@varSQL) EXEC (@varSQL) FETCH NEXT FROM @getTBName INTO @TableName END CLOSE @getTBName DEALLOCATE @getTBName ----select * from b ----select * from c


方法丙:

+ expand sourceview plaincopy to clipboardprint?

   1. Declare @t table(query varchar(2000),tables varchar(100)) 
   2. Insert into @t 
   3.     select 'Truncate table ['+T.table_name+']', T.Table_Name from INFORMATION_SCHEMA.TABLES T 
   4.     left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC 
   5.     on T.table_name=TC.table_name 
   6.     where (TC.constraint_Type ='Foreign Key' or TC.constraint_Type is NULL) and 
   7.     T.table_name not in ('dtproperties','sysconstraints','syssegments') and 
   8.     Table_type='BASE TABLE' 
   9. Insert into @t 
  10.     select 'delete from ['+T.table_name+']', T.Table_Name from INFORMATION_SCHEMA.TABLES T 
  11.         left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC 
  12.        on T.table_name=TC.table_name where TC.constraint_Type ='Primary Key' and T.table_name <>'dtproperties'and Table_type='BASE TABLE' 
  13. Declare @sql varchar(8000) 
  14. Select @sql=IsNull(@sql+' ','')+ query from @t 
  15. print(@sql) 
  16. Exec(@sql) 

Declare @t table(query varchar(2000),tables varchar(100)) Insert into @t select 'Truncate table ['+T.table_name+']', T.Table_Name from INFORMATION_SCHEMA.TABLES T left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC on T.table_name=TC.table_name where (TC.constraint_Type ='Foreign Key' or TC.constraint_Type is NULL) and T.table_name not in ('dtproperties','sysconstraints','syssegments') and Table_type='BASE TABLE' Insert into @t select 'delete from ['+T.table_name+']', T.Table_Name from INFORMATION_SCHEMA.TABLES T left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC on T.table_name=TC.table_name where TC.constraint_Type ='Primary Key' and T.table_name <>'dtproperties'and Table_type='BASE TABLE' Declare @sql varchar(8000) Select @sql=IsNull(@sql+' ','')+ query from @t print(@sql) Exec(@sql)

再来看看第二种需求: 表是空的,并且自增长列可以从1开始增长 。
这种需求其实和第一种差不多。 因为我们在以上语句中使用的是 truncate table 语句,所以,表的自增长 列是默认从头重新的。

关键是第三种需求: 表是空的,并且自增长列可以从1开始增长 ,而且存在表间的约束 。
这是个比较头痛的问题。因为外键约束,不能使用truncate table语句,但是,如果使用delete,又不能使自增长列从1开始重排。

我们不妨先来增加一些约束条件:

+ expand sourceview plaincopy to clipboardprint?

   1. CREATE TABLE [d] ( 
   2.     [id] [int] IDENTITY (1, 1) NOT NULL , 
   3.     [da] [int] NULL , 
   4.     [db] [int] NULL , 
   5.     CONSTRAINT [PK_d] PRIMARY KEY  CLUSTERED  
   6.     ( 
   7.         [id] 
   8.     )  ON [PRIMARY]  
   9. ) ON [PRIMARY] 
  10. CREATE TABLE [e] ( 
  11.     [id] [int] IDENTITY (1, 1) NOT NULL , 
  12.     [da] [int] NULL , 
  13.     [db] [int] NULL , 
  14.     [did] [int] NULL , 
  15.     CONSTRAINT [FK_e_d] FOREIGN KEY  
  16.     ( 
  17.         [did] 
  18.     ) REFERENCES [d] ( 
  19.         [id] 
  20.     ) 
  21. ) ON [PRIMARY] 
  22. insert into d 
  23. select 5,6 union all 
  24. select 7,8 union all 
  25. select 9,9 
  26. insert into e 
  27. select 8,6,1 union all 
  28. select 8,8,2 union all 
  29. select 8,9,2 

CREATE TABLE [d] ( [id] [int] IDENTITY (1, 1) NOT NULL , [da] [int] NULL , [db] [int] NULL , CONSTRAINT [PK_d] PRIMARY KEY CLUSTERED ( [id] ) ON [PRIMARY] ) ON [PRIMARY] CREATE TABLE [e] ( [id] [int] IDENTITY (1, 1) NOT NULL , [da] [int] NULL , [db] [int] NULL , [did] [int] NULL , CONSTRAINT [FK_e_d] FOREIGN KEY ( [did] ) REFERENCES [d] ( [id] ) ) ON [PRIMARY] insert into d select 5,6 union all select 7,8 union all select 9,9 insert into e select 8,6,1 union all select 8,8,2 union all select 8,9,2

此时再来执行甲乙丙语句时会提示:“无法截断表 'd',因为该表正由 FOREIGN KEY 约束引用。”

我们可以这样设想:
1、先找出没有外键约束的表,truncate
2、有外键的表,先delete,再复位identity列
于是得出,
语句丁(注意没有使用游标 )

+ expand sourceview plaincopy to clipboardprint?

   1. SET NoCount ON 
   2.    DECLARE @tableName varchar(512) 
   3.    Declare @SQL varchar(2048) 
   4.    SET @tableName='' 
   5.    WHILE EXISTS 
   6.    (    
   7.    --Find all child tables and those which have no relations 
   8.    SELECT T.table_name   FROM INFORMATION_SCHEMA.TABLES T 
   9.           LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC    ON T.table_name = TC.table_name 
  10.      WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL ) 
  11.          AND T.table_name NOT IN ( 'dtproperties', 'sysconstraints', 'syssegments' ) 
  12.          AND Table_type = 'BASE TABLE' 
  13.          AND T.table_name > @TableName 
  14.          ) 
  15.     Begin 
  16.         SELECT @tableName = min(T.table_name)    FROM INFORMATION_SCHEMA.TABLES T 
  17.         LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC    ON T.table_name=TC.table_name 
  18.            WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL ) 
  19.          AND T.table_name NOT IN ( 'dtproperties', 'sysconstraints', 'syssegments' ) 
  20.          AND Table_type = 'BASE TABLE' 
  21.          AND T.table_name > @TableName 
  22.          --Truncate the table 
  23.          SET @SQL = 'Truncate table '+ @TableName  
  24.          print (@SQL) 
  25.          Exec(@SQL) 
  26.      End 
  27.    
  28.    SET @TableName='' 
  29.    WHILE EXISTS 
  30.    (  
  31.    --Find all Parent tables 
  32.      SELECT T.table_name     FROM INFORMATION_SCHEMA.TABLES T 
  33.      LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC     ON T.table_name = TC.table_name 
  34.      WHERE TC.constraint_Type = 'Primary Key' 
  35.      AND T.table_name <> 'dtproperties' 
  36.      AND Table_type='BASE TABLE' 
  37.      AND T.table_name > @TableName 
  38.      ) 
  39.    Begin 
  40.      SELECT @tableName = min(T.table_name)   FROM INFORMATION_SCHEMA.TABLES T 
  41.           LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC   ON T.table_name=TC.table_name 
  42.      WHERE TC.constraint_Type = 'Primary Key' 
  43.      AND T.table_name <> 'dtproperties' 
  44.      AND Table_type = 'BASE TABLE' 
  45.      AND T.table_name > @TableName 
  46.      --Delete the table 
  47.      
  48.         SET @SQL = ' delete from '+ @TableName  
  49.          print (@SQL) 
  50.          Exec(@SQL) 
  51.      --Reset identity column 
  52.          IF EXISTS ( SELECT *   FROM INFORMATION_SCHEMA.COLUMNS 
  53.              WHERE COLUMNPROPERTY( 
  54.              OBJECT_ID( QUOTENAME(table_schema)+ '.' + QUOTENAME(@tableName) ), 
  55.              column_name,'IsIdentity' 
  56.              ) = 1 
  57.            ) 
  58.      DBCC CHECKIDENT(@tableName,RESEED,0) 
  59.    End 
  60.    SET NoCount OFF 

SET NoCount ON DECLARE @tableName varchar(512) Declare @SQL varchar(2048) SET @tableName='' WHILE EXISTS ( --Find all child tables and those which have no relations SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name = TC.table_name WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL ) AND T.table_name NOT IN ( 'dtproperties', 'sysconstraints', 'syssegments' ) AND Table_type = 'BASE TABLE' AND T.table_name > @TableName ) Begin SELECT @tableName = min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL ) AND T.table_name NOT IN ( 'dtproperties', 'sysconstraints', 'syssegments' ) AND Table_type = 'BASE TABLE' AND T.table_name > @TableName --Truncate the table SET @SQL = 'Truncate table '+ @TableName print (@SQL) Exec(@SQL) End SET @TableName='' WHILE EXISTS ( --Find all Parent tables SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name = TC.table_name WHERE TC.constraint_Type = 'Primary Key' AND T.table_name <> 'dtproperties' AND Table_type='BASE TABLE' AND T.table_name > @TableName ) Begin SELECT @tableName = min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE TC.constraint_Type = 'Primary Key' AND T.table_name <> 'dtproperties' AND Table_type = 'BASE TABLE' AND T.table_name > @TableName --Delete the table SET @SQL = ' delete from '+ @TableName print (@SQL) Exec(@SQL) --Reset identity column IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMNPROPERTY( OBJECT_ID( QUOTENAME(table_schema)+ '.' + QUOTENAME(@tableName) ), column_name,'IsIdentity' ) = 1 ) DBCC CHECKIDENT(@tableName,RESEED,0) End SET NoCount OFF

小结:除了以上方法,还可以临时禁用外键约束。语句为:
view plaincopy to clipboardprint?

   1. -- --禁用所有约束 
   2. --exec sp_msforeachtable 'alter table ? nocheck CONSTRAINT all' 
   3. -- --再启用所有外键约束 
   4. --exec sp_msforeachtable 'alter table ? check constraint all' 
  相关解决方案