2009-12-31 67 views
1

我正在尝试设置一个测试数据库,以针对自动化测试运行。我理解我们应该使用模拟对象,但这是一个旧的应用程序,这样做并不像应该那样容易。数据库中有太多的逻辑。不管怎样,足够的背景故事。我得到一个干净的数据库设置,测试可以加载已知数据,因此结果也是已知的。保持数据库结构和特效同步

在测试开始时,将运行一个.sql脚本来清​​空表格,然后用测试数据填充它们。我看到的问题并不是让数据库结构保持同步,因为它们变化不大(虽然这也会很好),但是要将所有的特效/函数等从开发中移到开始时的测试中测试。

是否有SQL命令可以执行此操作?从开发数据库读取一个proc,并将其复制到测试数据库?

编辑:我实际上发现使用SQL管理对象工作得很好。

唯一的问题是,如果有人重命名了一个项目,内部引用不会被sql server更新,并且它是在旧名称下创建的。有没有办法来解决这个问题?

+0

两台服务器是否连接?或者两个数据库都在同一台服务器上?换句话说,我们可以假设一个SQL脚本可以访问这两个数据库吗? – Aaronaught 2009-12-31 20:06:25

+0

同一台服务器,不同的数据库。 – CaffGeek 2009-12-31 20:10:22

+0

重命名操作使用sp_rename,它不会触发任何DDL触发器,因此没有简单的方法来记录这些。但是根据你想要完成的工作,为什么不从开发数据库拷贝数据库之前,在测试数据库中删除全部**函数/过程呢? – Aaronaught 2010-01-01 19:19:42

回答

0

有了SMO,下面的作品很棒!并在〜40秒内复制。

private static void CopyDBSchema(string sourceDBServer, string sourceDBName, string targetDBServer, string targetDBName) 
    { 
     Server server = new Server(sourceDBServer); 
     server.SetDefaultInitFields(true); 

     Database db = server.Databases[sourceDBName]; 
     Transfer t = new Transfer() 
     { 
      Database = db, 

      CopyData = false, 
      CopyAllObjects = false, 
      CopyAllUsers = false, 
      CopyAllLogins = false, 

      CopySchema = true, 
      CopyAllTables = true, 
      CopyAllViews = true, 
      CopyAllStoredProcedures = true, 
      CopyAllDatabaseTriggers = true, 
      CopyAllUserDefinedAggregates = true, 
      CopyAllUserDefinedDataTypes = true, 
      CopyAllUserDefinedFunctions = true, 
      CopyAllUserDefinedTypes = true, 

      DropDestinationObjectsFirst = true, 
      UseDestinationTransaction = true, 
      DestinationServer = targetDBServer, 
      DestinationDatabase = targetDBName 
     }; 

     t.Options.WithDependencies = true; 
     t.Options.IncludeIfNotExists = true; 
     t.Options.DriPrimaryKey = true; 
     t.Options.DriForeignKeys = true; 
     t.Options.DriIndexes = true; 
     t.Options.DriNonClustered = true; 
     t.Options.DriUniqueKeys = true; 
     t.Options.DriAllKeys = true; 
     t.Options.Triggers = true; 

     t.TransferData(); 
     server = null; 
    } 
+0

实际上,它复制了一切,除了因为某些原因没有标识设置的键。 – CaffGeek 2010-01-05 18:15:24

+0

需要应用Service Pack – CaffGeek 2010-01-05 22:41:06

3

你说保持“数据库结构”同步并不是一个问题,但是你继续说你需要从开发移动特殊功能/测试功能。这些是数据库结构的一部分! IAC,我会建议像Red-Gate的SQL Compare这样的工具。它将移动dev上存在的任何不存在于测试上的数据库结构。非常好的工具。我用了很多年。

+0

@Randy,当我说“结构”时,我的意思是“表格结构”。我们有SQL Compare,它的效果很好。但我想自动化这种能力。我不想知道在每次运行测试之前运行该工具以检查数据库结构是否相同。我希望通过调用一个将从1分贝复制到另一个分支的过程来理想地在.NET代码中处理这个检查。 – CaffGeek 2009-12-31 20:12:23

+0

@Chad - 你是否知道SQL比较可以从命令行运行,因此以自动化的方式运行? – 2009-12-31 20:17:26

+0

@Randy - 它并没有安装到任何地方。 – CaffGeek 2009-12-31 20:24:34

3

乍得,我不知道你如何使用这个自动化。如果你想立刻编写所有的特效,你可以从SQL企业管理器中完成。

在每个测试脚本之前,所有从Dev开发的过程对于CREATE。在TEST中放下你的proc并从dev文件运行脚本。这将确保你的procs同步。

1

这里有一个快速和肮脏的SQL脚本,您可以使用存储过程从一个数据库复制到另一个:

USE DestinationDatabase 

GO 

DECLARE 
    @SchemaName sysname, 
    @ProcName nvarchar(4000), 
    @ProcDefinition nvarchar(max), 
    @DropSql nvarchar(4000) 

SET @SchemaName = 'dbo' 

DECLARE crProcedures CURSOR FAST_FORWARD FOR 
    SELECT r.ROUTINE_NAME, r.ROUTINE_DEFINITION 
    FROM SourceDatabase.INFORMATION_SCHEMA.Routines r 
    WHERE ROUTINE_SCHEMA = @SchemaName 
    AND ROUTINE_NAME IN ('Procedure1', 'Procedure2', 'Procedure3') 
OPEN crProcedures 
FETCH NEXT FROM crProcedures INTO @ProcName, @ProcDefinition 
WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SET @DropSql = 'IF EXISTS ' + 
     '(SELECT * FROM sys.objects ' + 
     'WHERE object_id = OBJECT_ID(N''' + @ProcName + ''') ' + 
     'AND type in (N''P'', N''PC'')) ' + 
     'DROP PROCEDURE ' + @ProcName 
    EXEC sp_executesql @DropSql 
    EXEC sp_executesql @ProcDefinition 

    FETCH NEXT FROM crProcedures INTO @ProcName, @ProcDefinition 
END 
CLOSE crProcedures 
DEALLOCATE crProcedures 

只要确保你不要混淆SourceDatabaseDestinationDatabase,否则你会遇到麻烦!