在实际应用中,当我们准备把一个项目移交至客户手中使用时,我们需要把库中所有表先前的测试数据清空,以给客户一个干净的数据库,如果涉及的表很多,要一一的清空,不仅花费时间,还容易出错以及漏删,在这儿我提供了一个方法,可快捷有效的清空指定数据库所有表的数据。仅供参考,欢迎交流不同意见。
--Remove all data from a database SET NOCOUNT ON --Tables to ignore DECLARE @IgnoreTables TABLE (TableName varchar(512)) INSERT INTO @IgnoreTables (TableName) VALUES ('sysdiagrams') DECLARE @AllRelationships TABLE (ForeignKey varchar(512) ,TableName varchar(512) ,ColumnName varchar(512) ,ReferenceTableName varchar(512) ,ReferenceColumnName varchar(512) ,DeleteRule varchar(512)) INSERT INTO @AllRelationships SELECT f.name AS ForeignKey, OBJECT_NAME(f.parent_object_id) AS TableName, COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName, OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName, delete_referential_action_desc as DeleteRule FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id DECLARE @TableOwner varchar(512) DECLARE @TableName varchar(512) DECLARE @ForeignKey varchar(512) DECLARE @ColumnName varchar(512) DECLARE @ReferenceTableName varchar(512) DECLARE @ReferenceColumnName varchar(512) DECLARE @DeleteRule varchar(512) PRINT('Loop through all tables and switch all constraints to have a delete rule of CASCADE') DECLARE DataBaseTables0 CURSOR FOR SELECT SCHEMA_NAME(t.schema_id) AS schema_name, t.name AS table_name FROM sys.tables AS t; OPEN DataBaseTables0; FETCH NEXT FROM DataBaseTables0 INTO @TableOwner,@TableName; WHILE @@FETCH_STATUS = 0 BEGIN IF (NOT EXISTS(SELECT TOP 1 1 FROM @IgnoreTables WHERE TableName = @TableName)) BEGIN PRINT '['+@TableOwner+'].[' + @TableName + ']'; DECLARE DataBaseTableRelationships CURSOR FOR SELECT ForeignKey, ColumnName, ReferenceTableName, ReferenceColumnName FROM @AllRelationships WHERE TableName = @TableName OPEN DataBaseTableRelationships; FETCH NEXT FROM DataBaseTableRelationships INTO @ForeignKey, @ColumnName, @ReferenceTableName, @ReferenceColumnName; IF @@FETCH_STATUS <> 0 PRINT '=====> No Relationships' ; WHILE @@FETCH_STATUS = 0 BEGIN PRINT '=====> switching delete rule on ' + @ForeignKey + ' to CASCADE'; BEGIN TRANSACTION BEGIN TRY EXEC(' ALTER TABLE ['+@TableOwner+'].[' + @TableName + '] DROP CONSTRAINT '+@ForeignKey+'; ALTER TABLE ['+@TableOwner+'].[' + @TableName + '] ADD CONSTRAINT '+@ForeignKey+' FOREIGN KEY ( '+@ColumnName+' ) REFERENCES '+@ReferenceTableName+' ( '+@ReferenceColumnName+' ) ON DELETE CASCADE; '); COMMIT TRANSACTION END TRY BEGIN CATCH PRINT '=====> can''t switch ' + @ForeignKey + ' to CASCADE, - ' + CAST(ERROR_NUMBER() AS VARCHAR) + ' - ' + ERROR_MESSAGE(); ROLLBACK TRANSACTION END CATCH; FETCH NEXT FROM DataBaseTableRelationships INTO @ForeignKey, @ColumnName, @ReferenceTableName, @ReferenceColumnName; END; CLOSE DataBaseTableRelationships; DEALLOCATE DataBaseTableRelationships; END PRINT ''; PRINT ''; FETCH NEXT FROM DataBaseTables0 INTO @TableOwner,@TableName; END CLOSE DataBaseTables0; DEALLOCATE DataBaseTables0; PRINT('Loop though each table and DELETE All data from the table') DECLARE DataBaseTables1 CURSOR FOR SELECT SCHEMA_NAME(t.schema_id) AS schema_name, t.name AS table_name FROM sys.tables AS t; OPEN DataBaseTables1; FETCH NEXT FROM DataBaseTables1 INTO @TableOwner,@TableName; WHILE @@FETCH_STATUS = 0 BEGIN IF (NOT EXISTS(SELECT TOP 1 1 FROM @IgnoreTables WHERE TableName = @TableName)) BEGIN PRINT '['+@TableOwner+'].[' + @TableName + ']'; PRINT '=====> deleting data from ['+@TableOwner+'].[' + @TableName + ']'; BEGIN TRY EXEC(' DELETE FROM ['+@TableOwner+'].[' + @TableName + '] DBCC CHECKIDENT ([' + @TableName + '], RESEED, 0) '); END TRY BEGIN CATCH PRINT '=====> can''t FROM ['+@TableOwner+'].[' + @TableName + '], - ' + CAST(ERROR_NUMBER() AS VARCHAR) + ' - ' + ERROR_MESSAGE(); END CATCH; END PRINT ''; PRINT ''; FETCH NEXT FROM DataBaseTables1 INTO @TableOwner,@TableName; END CLOSE DataBaseTables1; DEALLOCATE DataBaseTables1; PRINT('Loop through all tables and switch all constraints to have a delete rule they had at the beggining of the task') DECLARE DataBaseTables2 CURSOR FOR SELECT SCHEMA_NAME(t.schema_id) AS schema_name, t.name AS table_name FROM sys.tables AS t; OPEN DataBaseTables2; FETCH NEXT FROM DataBaseTables2 INTO @TableOwner,@TableName; WHILE @@FETCH_STATUS = 0 BEGIN IF (NOT EXISTS(SELECT TOP 1 1 FROM @IgnoreTables WHERE TableName = @TableName)) BEGIN PRINT '['+@TableOwner+'].[' + @TableName + ']'; DECLARE DataBaseTableRelationships CURSOR FOR SELECT ForeignKey, ColumnName, ReferenceTableName, ReferenceColumnName, DeleteRule FROM @AllRelationships WHERE TableName = @TableName OPEN DataBaseTableRelationships; FETCH NEXT FROM DataBaseTableRelationships INTO @ForeignKey, @ColumnName, @ReferenceTableName, @ReferenceColumnName, @DeleteRule; IF @@FETCH_STATUS <> 0 PRINT '=====> No Relationships' ; WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @switchBackTo varchar(50) = CASE WHEN @DeleteRule = 'NO_ACTION' THEN 'NO ACTION' WHEN @DeleteRule = 'CASCADE' THEN 'CASCADE' WHEN @DeleteRule = 'SET_NULL' THEN 'SET NULL' WHEN @DeleteRule = 'SET_DEFAULT' THEN 'SET DEFAULT' END PRINT '=====> switching delete rule on ' + @ForeignKey + ' to ' + @switchBackTo; BEGIN TRANSACTION BEGIN TRY EXEC(' ALTER TABLE ['+@TableOwner+'].[' + @TableName + '] DROP CONSTRAINT '+@ForeignKey+'; ALTER TABLE ['+@TableOwner+'].[' + @TableName + '] ADD CONSTRAINT '+@ForeignKey+' FOREIGN KEY ( '+@ColumnName+' ) REFERENCES '+@ReferenceTableName+' ( '+@ReferenceColumnName+' ) ON DELETE '+@switchBackTo+' '); COMMIT TRANSACTION END TRY BEGIN CATCH PRINT '=====> can''t change '+@ForeignKey + ' back to '+ @switchBackTo +', - ' + CAST(ERROR_NUMBER() AS VARCHAR) + ' - ' + ERROR_MESSAGE(); ROLLBACK TRANSACTION END CATCH; FETCH NEXT FROM DataBaseTableRelationships INTO @ForeignKey, @ColumnName, @ReferenceTableName, @ReferenceColumnName, @DeleteRule; END; CLOSE DataBaseTableRelationships; DEALLOCATE DataBaseTableRelationships; END PRINT ''; PRINT ''; FETCH NEXT FROM DataBaseTables2 INTO @TableOwner,@TableName; END CLOSE DataBaseTables2; DEALLOCATE DataBaseTables2;
原文地址:http://www.cnblogs.com/huyong/archive/2012/01/17/2323663.html