0

在我的集成测试期间,我尝试使用以下方法删除数据库:

USE master
ALTER DATABASE TestXyz SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE TestXyz

然而,很多时候(考虑到测试的数量)应用程序后台进程之一设法在SET SINGLE_USER和之间DROP DATABASE,这使得它成为数据库的单一用户并打破DROP.

我不能使用RESTRICTED_USER,因为应用程序当前有db_owner权限(由于大量遗留代码,其中一些需要它,所以它不会仅仅为了测试而改变)。

我不能使用OFFLINE,因为它不会从磁盘中删除数据库文件。

你将如何解决这个问题?

4

3 回答 3

1

好的计划 b... 迭代一滴连接并重命名数据库以使其远离应用程序域。然后放下它。为了处理通过连接的迭代,重命名上的 try catch 将有望允许它运行,直到它能够断开连接。下面的示例代码创建了一个 DB TestDB;在 while 循环中将其重命名为 testdb2,然后在循环成功后将其删除。

-- Setup a scratch Db for testing
create database testdb
go
use testdb

while exists (select name from sys.databases where name = 'testdb')
Begin
  DECLARE @DbName nvarchar(50) SET @DbName = N'testdb'

    DECLARE @EXECSQL varchar(max) SET @EXECSQL = ''

    SELECT @EXECSQL = @EXECSQL + 'Kill ' + Convert(varchar, SPId) + ';' 
    FROM MASTER..SysProcesses 
    WHERE DBId = DB_ID(@DbName) AND SPId <> @@SPId

    EXEC(@EXECSQL)

    Begin try
        EXEC sp_renamedb 'testdb', 'testdb2'
    end try
    Begin Catch
    print 'failed to rename'
    End Catch
end

drop database testdb2
于 2012-08-28T07:17:58.007 回答
0

我终于使用以下方法解决了它:

ALTER LOGIN MyAppUser DISABLE
ALTER DATABASE TestXyz SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE TestXyz
ALTER LOGIN MyAppUser ENABLE

由于我可以使用不同的登录来测试数据库管理过程,这允许我阻止应用程序访问数据库。(这里的原因SINGLE_USER只是为了踢已经连接的用户。我没有检查是否ALTER LOGIN已经这样做了,但我认为它没有)。

另一种选择是在删除MyAppUser之前从数据库中删除它,但是我现在才想到它并且没有代码。

于 2012-08-28T23:06:05.903 回答
0

Try this once:

  1. Stop application services and run your query.
  2. Stop application services and restart SQL Server Services and then run your query.
于 2012-08-28T06:33:15.147 回答