在我的集成测试期间,我尝试使用以下方法删除数据库:
USE master
ALTER DATABASE TestXyz SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE TestXyz
然而,经常(考虑到测试次数),其中一个应用程序后台进程设法在SET SINGLE_USER
和DROP DATABASE
之间进行,这使得它成为数据库的单个用户并打破{{1 }}
我无法使用DROP
,因为应用程序当前具有RESTRICTED_USER
权限(由于大量遗留代码,其中一些需要它,因此不会仅仅针对测试进行更改)。
我无法使用db_owner
,因为它不会从磁盘中删除数据库文件。
你会如何解决这个问题?
答案 0 :(得分: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
答案 1 :(得分:0)
尝试一次:
SQL Server Services
,然后运行查询。 答案 2 :(得分: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
,但是我只考虑它并且没有代码。