DB|使用TRUNCATE TABLE完成DB清洗

打包程序时,往往需要把测试数据清除掉,最直接的方法是,导出SQL脚本时,只导出结构。但如果使用备份还原的模式,清除数据记录就会有点麻烦,尤其使用自增字段为主键,delete之后数据清空,但增长的初始值还是基于原有数据。

如果表不多的话,可以使用逐个TRUNCATE TABLE命令。如果表比较多的时候,写个for循环也就OK了,但还需注意一个细节,即表中可能存在外键,如果不处理,是无法清除数据的,因此在循环之前先使用系统存储过程sp_MSforeachtable禁用外键检测,清除完成后,再打开就可以了。

use dbname;

--禁用表中所有的外键

EXEC sp_MSforeachtable @command1='alter table?  NOCHECK constraint all';

--查询数据到临时表 生成有序index列 用于后面遍历

select row_number() over(order by name desc) as 'rowindex',* into #test_temp from ( SELECT name FROM SysObjects Where XType='U') as A;

--遍历数据表test中的数据

declare @i int,@flag int

select @flag=count(rowindex)+1 from #test_temp

set @i=1

declare @v1 varchar(500)

while(@i<@flag)

begin

select @v1=name from #test_temp where rowindex=@i ;

exec('TRUNCATE TABLE '+ @v1);

--清除数据表

set @i=@i+1;

end

--启用数据表中的外键

EXEC sp_MSforeachtable @command1='alter table?  CHECK constraint all';

--删除临时表

drop table #test_temp

在我本机测试过之后,移到服务器执行出现外键的问题,报错如下。

查询资料之后,发现以上代码可以有更简单的写法。

--关闭约束

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

--关闭触发器

EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'

--清空表

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'

--启用约束

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

--启用触发器

EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'

但简单归简单,却不能从根本上解决问题。继续查询,最后找到一个折中的方案,即遍历库中所有的表,然后把表中的自增字段重设种子,之后清除DB的的日志信息。

if( object_id('pr_DataClear') is not null )

drop procedure pr_DataClear

go

create procedure pr_DataClear

as

begin transaction

declare @cTblName varchar(128)

declare cur_Clear cursor for select rtrim(name) from sysobjects where type = 'U' order by crdate desc

open cur_Clear

declare @cSQL varchar(255)

fetch next from cur_Clear into @cTblName

while( @@fetch_status = 0)

begin

set @cSQL = 'delete from ' + @cTblName

print @cSQL

exec( @cSQL )

if( ident_seed(@cTblName) is not null )

begin

dbcc checkident( @cTblName, reseed, 0 )

print '有种子且成功重置为1'

end

fetch next from cur_Clear into @cTblName

end

close cur_Clear

deallocate cur_Clear

commit

go

-- 清空所有表数据

exec pr_DataClear

-- 截断日志

ALTER DATABASE DBName SET RECOVERY SIMPLE

dbcc shrinkdatabase( DBName )

dbcc updateusage( DBName )

问题解决,使用时,替换脚本中的DBName为你的数据库名。谨慎操作,数据丢失不可恢复。如有更好方案,还请共享。

你可能感兴趣的:(DB|使用TRUNCATE TABLE完成DB清洗)