首页  ·  知识 ·  数据库
MSSQL中如何用SQL清除所有表的数据
网友   http://blog.csdn.net/downmoon/archive/2009/09/10/4540863.aspx  MS-SQL  编辑:德仔   图片来源:网络
有朋友问起:MSSQL中如何用SQL清除所有表的数据?这个需求分三种类型: 第一:只要数据库中表是空的; 第二

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

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

方法甲:

  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. 方法乙:
    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  
    •  


      方法丙:

       



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

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

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

       

  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  
    •  

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

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

  30. SET NoCount ON   
  31.    DECLARE @tableName varchar(512)   
  32.    Declare @SQL varchar(2048)   
  33.    SET @tableName=''  
  34.    WHILE EXISTS   
  35.    (      
  36.    --Find all child tables and those which have no relations   
  37.    SELECT T.table_name   FROM INFORMATION_SCHEMA.TABLES T   
  38.           LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC    ON T.table_name = TC.table_name   
  39.      WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL )   
  40.          AND T.table_name NOT IN ( 'dtproperties''sysconstraints''syssegments' )   
  41.          AND Table_type = 'BASE TABLE'  
  42.          AND T.table_name > @TableName   
  43.          )   
  44.     Begin   
  45.         SELECT @tableName = min(T.table_name)    FROM INFORMATION_SCHEMA.TABLES T   
  46.         LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC    ON T.table_name=TC.table_name   
  47.            WHERE ( TC.constraint_Type = 'Foreign Key' OR TC.constraint_Type IS NULL )   
  48.          AND T.table_name NOT IN ( 'dtproperties''sysconstraints''syssegments' )   
  49.          AND Table_type = 'BASE TABLE'  
  50.          AND T.table_name > @TableName   
  51.          --Truncate the table   
  52.          SET @SQL = 'Truncate table '+ @TableName    
  53.          print (@SQL)   
  54.          Exec(@SQL)   
  55.      End   
  56.      
  57.    SET @TableName=''  
  58.    WHILE EXISTS   
  59.    (    
  60.    --Find all Parent tables   
  61.      SELECT T.table_name     FROM INFORMATION_SCHEMA.TABLES T   
  62.      LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC     ON T.table_name = TC.table_name   
  63.      WHERE TC.constraint_Type = 'Primary Key'  
  64.      AND T.table_name <> 'dtproperties'  
  65.      AND Table_type='BASE TABLE'  
  66.      AND T.table_name > @TableName   
  67.      )   
  68.    Begin   
  69.      SELECT @tableName = min(T.table_name)   FROM INFORMATION_SCHEMA.TABLES T   
  70.           LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC   ON T.table_name=TC.table_name   
  71.      WHERE TC.constraint_Type = 'Primary Key'  
  72.      AND T.table_name <> 'dtproperties'  
  73.      AND Table_type = 'BASE TABLE'  
  74.      AND T.table_name > @TableName   
  75.      --Delete the table   
  76.        
  77.         SET @SQL = ' delete from '+ @TableName    
  78.          print (@SQL)   
  79.          Exec(@SQL)   
  80.      --Reset identity column   
  81.          IF EXISTS ( SELECT *   FROM INFORMATION_SCHEMA.COLUMNS   
  82.              WHERE COLUMNPROPERTY(   
  83.              OBJECT_ID( QUOTENAME(table_schema)+ '.' + QUOTENAME(@tableName) ),   
  84.              column_name,'IsIdentity'  
  85.              ) = 1   
  86.            )   
  87.      DBCC CHECKIDENT(@tableName,RESEED,0)   
  88.    End   结:除了以上方法,还可以临时禁用外键约束。语句为:
    1. -- --禁用所有约束   
    2. --exec sp_msforeachtable 'alter table ? nocheck CONSTRAINT all'  
    3. -- --再启用所有外键约束   
    4. --exec sp_msforeachtable 'alter table ? check constraint all'
  89.  

本文作者:网友 来源: http://blog.csdn.net/downmoon/archive/2009/09/10/4540863.aspx
CIO之家 www.ciozj.com 微信公众号:imciow
    >>频道首页  >>网站首页   纠错  >>投诉
版权声明:CIO之家尊重行业规范,每篇文章都注明有明确的作者和来源;CIO之家的原创文章,请转载时务必注明文章作者和来源;
延伸阅读