I am currently building unit tests that tests if some classes are editing a sql server 2005 database correctly. To do this I have created a small subset of data from our production and are storing it as a backup file. Whenever a unit test needs to be sure it has a clean database state it calls a restore routine that basically call the following sql:
RESTORE DATABASE database FROM DISK = 'c:\test\backup.bak' WITH REPLACE, NORECOVERY
This normally works, and has decent speed. When I say normally it’s because sometimes the database gets stuck in ‘restore’ mode result in error messages that looks like this (assuming it’s a Alter command):
ALTER DATABASE is not permitted while a database is in the Restoring state.
This means that if the first fail, every test fails. I can get the database out of it stuck state, but it’s rather irritating to do it every single time, it’s very time consuming and the whole point of unit testing was so I didn’t need anything when I activate the test.
I tried to see if I could avoid it by the RESTORE syntax, but can’t kind any options or flags that sound like it could resolve the issue.
Is there any other method I could use that is a lot safer that the RESTORE command?
Update:
I discovered that the restore fail happens mostly when a connection was still active. I usually handled that issue with the following structure:
ALTER DATABASE MyDatabase SET Single_User WITH Rollback Immediate
-- Restore logic here
ALTER DATABASE MyDatabase SET Multi_User
The problem with this is that it only limits all the connections to one. Sometimes one of the connections that is forced to close jumps over to the only one free, disrupting the restore and making it fail (or that is what I can gather from the documents and pages I have been reading).
I am instead trying to do the following SQL command before I start on my restore logic:
Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id('Mydatabase')
While @spid Is Not Null
Begin
Execute ('Kill ' + @spid)
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id('Mydatabase') and spid > @spid
End
-- Do Restore Logic
http://geekswithblogs.net/AngelEyes/archive/2010/02/24/kill-connections-to-resote-db—sql-server.aspx
This section of code goes in and actively closes all connections, which gives the restore logic room to execute. I am, however, not entirely sure that this is the best way to go, simply because it does not prevent connections to reestablish, potentially disrupting the restore process again. But so far I haven’t seen evidence that this has happened yet.
By using usr’s suggestion and scripting my way through the restore process, I got it working. This answer is to close the question so visitor know I found the solution. The solution is described in the original question as an update.