I have the following SQL script:
USE MyDatabase
ALTER DATABASE MyDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
BEGIN TRANSACTION
-- Write to tables here
COMMIT TRANSACTION
ALTER DATABASE MyDatabase SET MULTI_USER
GO
I want to make sure that my database is not accessed while the script is running, which is why I am setting the database to SINGLE_USER at the top.
Now, if anything inside the transaction fails (e.g. syntax error) I will never reset the database back to MULTI_USER which means it will be stuck in single user mode permanently (not what I want).
Is there a way to ensure we always go back to MULTI_USER, even on failure?
I guess I’m looking for the equivalent of a finally block in SQL, but from what I have read this doesn’t exist. Is there another way?
It’s worth noting that I cannot move the ALTER DATABASE commands into the transaction, as this is not permitted (since they are committed immediately).
You should be able to use a TRY CATCH to make sure you always go back to
MULTI_USER.You will just need to move the command to switch back to
MULTI_USERright after theTRY CATCHblock, since FINALLY is not supported in SQL Server.I ran a quick test with the following SQL and it worked as expected in SQL Server 2005. Just make sure you
ROLLBACKthe transaction in theCATCHblock. I usedSELECT 1/0to force the code into theCATCHblock. For debugging purposes, I added theSELECT user_access_desc ...statements to show that the database was indeed switching from single user back to multi user mode.EDIT
In my original answer, I had the
ALTER ... MULTI_USERstatement inside both theTRYand theCATCHblock, but that was unnecessary so I moved the statement to right after theTRY CATCHblock. I also added some error reporting. Some things to watch out for with this approach are:@errNumand@errMsgvalues to a table (wrapped in a TRY CATCH), switch back toMULTI_USERmode, and then perform whatever other error handling measures that are required, as the local variables will go out of scope after theGOstatement.TRY CATCH. The documentation I linked to above does list out what those conditions are.