TSQL在sql-server中清除数据库的模式?

时间:2009-09-25 16:50:41

标签: sql sql-server tsql

我想在我的SqlServer实例上清除数据库的架构。我应该使用什么tsql?

通过模式我的意思是表,约束等。我希望结果类似于我创建一个新数据库,但是我不想实际删除和创建数据库。

为什么:

对于那些好奇的人,我需要清空架构而不丢弃,因为数据库被隔离用于单元测试的方式。在运行测试之前,会保存数据库的快照。每次测试运行后,都会恢复此快照。如果我将数据库操作保留在数据库范围内,我只能确保跨单元测试的一致状态。删除/创建数据库超出了db的范围(在master的范围内)。

在这种情况下,我需要声明当架构为空时会发生预期的事情。通过sql清空模式使测试方法保持一致:基本上做任何你想要的数据库,运行它,恢复它。

Raj More的回答让我开始了。我希望有人可以缩短这些过程。

2 个答案:

答案 0 :(得分:4)

想想我会分享我最终想出的东西。此脚本创建一个游标以循环db的INFORMATION_SCHEMA中的表。它会在表格上进行3次传递,包括外键,然后是主键,最后是表格本身。它基于Raj More的想法并考虑了devio的评论。

-- Helper Procedure
CREATE PROC #DropConstraints
  @tableSchema nvarchar(max),
  @tableName nvarchar(max),
  @constraintType nvarchar(20)
AS
BEGIN
  DECLARE @cName nvarchar(max);

  DECLARE constraint_cursor CURSOR FOR
    SELECT CONSTRAINT_NAME 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE 
      CONSTRAINT_TYPE = @constraintType
      AND TABLE_NAME = @tableName
      AND TABLE_SCHEMA = @tableSchema

  OPEN constraint_cursor

  FETCH NEXT FROM constraint_cursor INTO @cName
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC ('ALTER TABLE ' + @tableSchema + '.' + @tableName + ' DROP CONSTRAINT ' + @cName);
    FETCH NEXT FROM constraint_cursor INTO @cName
  END

  CLOSE constraint_cursor
  DEALLOCATE constraint_cursor
END
GO

-- DROP DATABASE TABLES
BEGIN TRANSACTION
  DECLARE @tableSchema varchar(max), @tableName varchar(max);

  -- Setup Cursor for looping
  DECLARE table_cursor SCROLL CURSOR FOR
    SELECT TABLE_SCHEMA, TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES

  OPEN table_cursor

  -- Drop Foreign Keys
  FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName
  WHILE @@FETCH_STATUS = 0
  BEGIN  
    EXEC #DropConstraints @tableSchema, @tableName, 'FOREIGN KEY';

    FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName
  END

  -- Drop Primary Keys
  FETCH FIRST FROM table_cursor INTO @tableSchema, @tableName
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC #DropConstraints @tableSchema, @tableName, 'PRIMARY KEY';

    FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName
  END

  -- Drop Tables
  FETCH FIRST FROM table_cursor INTO @tableSchema, @tableName
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC ('DROP TABLE ' + @tableSchema + '.' + @tableName);

    FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName
  END

  -- Cleanup
  CLOSE table_cursor
  DEALLOCATE table_cursor
COMMIT TRANSACTION
GO

答案 1 :(得分:2)

您可以使用INFORMATION_SCHEMA视图集生成SQL脚本以删除所有对象。

您不必删除索引,触发器,约束等项目,因为当您删除附加到的表时它们会被删除。

暴力警告

由于关系,现在桌子本身很棘手。

如果你将每个drop语句与GO分开,你可以继续运行脚本,直到你没有错误,然后你就会有一个干净的名单。

基于反馈的UnbruteForcing

现在,如果先删除所有外键,那么您可以一次性删除所有表。