How to drop a database when it's currently in use? - sql

NB. I don't want to mark the check box in the wizard for deletion. This question's strictly about scripting the behavior.
When I run the following script to get a fresh start, I get the error that the database Duck can't be deleted because it's currently in use.
use Master
drop database Duck
drop login WorkerLogin
drop login AdminLogin
go
Be that as it may (even though I'm the only user currently in the system and I run no other queries but that's another story), I need to close all the existing connections. One way is to wait it out or restart the manager. However I'd like to script in that behavior so I can tell the stubborn server to drop the duck down. (Yes, "typo" intended.)
What do I need to add to the dropping statement?

Try below code.
USE master;
ALTER DATABASE [Duck] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [Duck] ;
For deep discussion see this answer.

You have to kill first all active connections before you can drop the database.
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
--do you stuff here
ALTER DATABASE YourDatabase SET MULTI_USER
http://wiki.lessthandot.com/index.php/Kill_All_Active_Connections_To_A_Database
How do you kill all current connections to a SQL Server 2005 database?

if you're ssms tab is not currently on the db to be dropped (meaning you are in the master db), then these will help:
https://dba.stackexchange.com/questions/2387/sql-server-cannot-drop-database-dbname-because-it-is-currently-in-use-but-n
https://dba.stackexchange.com/questions/34264/how-to-force-drop-database-in-sql-server-2008

Related

SQL deadlocking..in single user mode now

Couple of databases produced an error this morning whilst running in Single User Mode. Due to the following error I am unable to do anything :(
Msg 1205, Level 13, State 68, Line 1
Transaction (Process ID 62) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
I receive that error when trying the following (using the Master Database as a Sys Admin):
ALTER DATABASE dbname
SET MULTI_USER;
GO
For the sake of it I have tried Restarting the SQL Server, I have tried killing any processes and I have even tried resetting the single user myself:
ALTER DATABASE dbname
SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
The job which was running was designed to copy the database and put it in single user mode immediately to try and make it faster.
Anyway I can remove the locks?
Had the same problem. This worked for me:
set deadlock_priority high; -- could also try "10" instead of "high" (5)
alter database dbname set multi_user; -- can also add "with rollback immediate"
From ideas/explanation:
http://myadventuresincoding.wordpress.com/2014/03/06...
http://www.sqlservercentral.com/blogs/pearlknows/2014/04/07/...
Ok, I will answer my own.
I had to use the following:
sp_who
which displayed details of the current connected users and sessions, I then remembered about Activity Monitor which shows the same sort of stuff...Anyway that led me away from my desk to some bugger who had maintained connections to the database against my wishes...
Anyway once I had shut the PC down (by unplugging it...deserved it) I could then run the SQL to amend it into MULTI_USER mode (using system admin user):
USE Master
GO
ALTER DATABASE dbname
SET MULTI_USER;
GO
FYI for those who care, this can be used to immediately set the DB to SINGLE_USER:
ALTER DATABASE dbname
SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
Further details, if you know the process id you can use kill pid:
kill 62
Bare in mind SSMS creates a process for your user as well, in my case this was being rejected due to another.
EDIT: As Per Bobby's recommendations we can use:
sp_Who2
This can show us which process is blocked by the other process.
tanks a lot.
SET DEADLOCK_PRIORITY HIGH ---- could also try "10" instead of "high" (5)
GO
ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE SET MULTI_USER
GO
When related system processes are at dead block scenario.
SPID 15 & SPID 29 - both are background SysProcesses.
This helps in such cases:
--------- START OF CMDs--------
SET DEADLOCK_PRIORITY HIGH ---- could also try "10" instead of "high" (5)
GO
ALTER DATABASE <dbname> SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE <dbname> SET MULTI_USER
GO
-------------------------- END OF CMDs ------------------
Blocking Case with an User DB RESTORE process putting DB in Single_User

Error In Database Renaming

I need to rename one of my database and tried a query like this
ALTER DATABASE Test MODIFY NAME = NewTest
But this throws an error
Msg 5030, Level 16, State 2, Line 1
The database could not be exclusively locked to perform the operation.
Can any one give me any suggestion?
Try something like;
USE master
GO
ALTER DATABASE Test
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE Test MODIFY NAME = NewTest
GO
ALTER DATABASE NewTest
SET MULTI_USER
GO
Be aware of the fact that this may not rename the physical file on the hard drive though.
There are a couple of things you need to investigate. The reason you're getting that error could be due to one or more of the following things:
The account you're using does not have permission to run the command
The DB is locked by another process/user
The database contains a file group that is read-only
You can try and force single user mode to check 2.
ALTER DATABASE SINGLE_USER ROLLBACK IMMEDIATE.
That will kill any concurrent connections to the DB allowing you to rule out number two.
You have two options:
Look for and kill all connections like OMG Priories suggest
Open the database in Single Server Mode as described here:
http://technet.microsoft.com/en-us/library/ms345598(v=sql.105).aspx

Roll back a entire database like I can with transactions

I am doing some testing on a dev database. I would like a easy way to roll back to a known state, however due to the size of the database restoring from a backup takes 5 minutes to perform.
The work I want to "Rollback" is distributed over many connections, I can not modify the sql for some of the connections because they are from an app I do not have access to the source (so I can't just wrap my connections with a giant BEGIN TRANSACTION)
Is there something lighter weight than restoring from a backup but I don't need to explicitly enable like BEGIN TRANSACTION and also works to roll back work done by connections that have opened, performed it's work, and closed after the point to rollback to was created?
You can use database snapshots at the beginning and revert to it at the end. You have to however have all connections closed as it is very similar to BACKUP/RESTORE, though it is certainly more lightweight. One way to do it is it kill all the connections before reverting. If your application can reconnect to a database after a connection failure,this should cover what you want to achieve.
----To create a snapshot
create database SrcDbSnapshot
on ( name = LogicalFileNameFromSrcDB,
filename = 'E:\SrcDB.ss')
AS SNAPSHOT OF SrcDB
go
----To roll back
--Kills all connections and performs the rollback
ALTER DATABASE [SrcDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [SrcDB] FROM DATABASE_SNAPSHOT = 'SrcDbSnapshot'
go
----To remove the snapshot
drop database SrcDbSnapshot
go

Stored procedure will not display in object explorer?

USE [MASTER]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [MASTER]
GO
CREATE PROCEDURE [dbo].[TOTALLY_NEW] #FISCAL_YEAR NVARCHAR(4) AS
BEGIN
PRINT 'HERE'
END
GO
select * from master..sysobjects
where name like 'tot%' <-- returns one row!!!!!!
I've refreshed this list a dozen times..!!
I've tried disconnecting and reconnecting..
I've created all those other SP's listed in the image before.
Here is a picture with more.
Ensure that the user you are using has permissions to view stored procedures. I am not 100% on SQL Server which permission this is but I have seen this problem on a few other databases where a user creates a SP, but another user does not have permission to view or list the SPs.
Per request, converting comment to answer:
Yes, you shouldn't be creating user objects in master. The only time I ever do it is when I explicitly want to create a utility procedure that I can call from any database using that database's context, which you have to do on purpose and doesn't happen by accident - so I suspect you inadvertently marked your object as a system procedure. You do this using EXEC sp_MS_marksystemobject (or in older versions by having set EXEC sp_MS_upd_sysobj_category 1 - the latter might work in 2005 with 80 compatibility, not sure).

ALTER DATABASE failed because a lock could not be placed on database

I need to restart a database because some processes are not working. My plan is to take it offline and back online again.
I am trying to do this in Sql Server Management Studio 2008:
use master;
go
alter database qcvalues
set single_user
with rollback immediate;
alter database qcvalues
set multi_user;
go
I am getting these errors:
Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
Msg 5061, Level 16, State 1, Line 4
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 4
ALTER DATABASE statement failed.
What am I doing wrong?
After you get the error, run
EXEC sp_who2
Look for the database in the list. It's possible that a connection was not terminated. If you find any connections to the database, run
KILL <SPID>
where <SPID> is the SPID for the sessions that are connected to the database.
Try your script after all connections to the database are removed.
Unfortunately, I don't have a reason why you're seeing the problem, but here is a link that shows that the problem has occurred elsewhere.
http://www.geakeit.co.uk/2010/12/11/sql-take-offline-fails-alter-database-failed-because-a-lock-could-not-error-5061/
I managed to reproduce this error by doing the following.
Connection 1 (leave running for a couple of minutes)
CREATE DATABASE TESTING123
GO
USE TESTING123;
SELECT NEWID() AS X INTO FOO
FROM sys.objects s1,sys.objects s2,sys.objects s3,sys.objects s4 ,sys.objects s5 ,sys.objects s6
Connections 2 and 3
set lock_timeout 5;
ALTER DATABASE TESTING123 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
Try this if it is "in transition" ...
http://learnmysql.blogspot.com/2012/05/database-is-in-transition-try-statement.html
USE master
GO
ALTER DATABASE <db_name>
SET OFFLINE WITH ROLLBACK IMMEDIATE
...
...
ALTER DATABASE <db_name> SET ONLINE
Just to add my two cents. I've put myself into the same situation, while searching the minimum required privileges of a db login to run successfully the statement:
ALTER DATABASE ... SET SINGLE_USER WITH ROLLBACK IMMEDIATE
It seems that the ALTER statement completes successfully, when executed with a sysadmin login, but it requires the connections cleanup part, when executed under a login which has "only" limited permissions like:
ALTER ANY DATABASE
P.S. I've spent hours trying to figure out why the "ALTER DATABASE.." does not work when executed under a login that has dbcreator role + ALTER ANY DATABASE privileges. Here's my MSDN thread!
I will add this here in case someone will be as lucky as me.
When reviewing the sp_who2 list of processes note the processes that run not only for the effected database but also for master. In my case the issue that was blocking the database was related to a stored procedure that started a xp_cmdshell.
Check if you have any processes in KILL/RollBack state for master database
SELECT *
FROM sys.sysprocesses
WHERE cmd = 'KILLED/ROLLBACK'
If you have the same issue, just the KILL command will probably not help.
You can restarted the SQL server, or better way is to find the cmd.exe under windows processes on SQL server OS and kill it.
In SQL Management Studio, go to Security -> Logins and double click your Login. Choose Server Roles from the left column, and verify that sysadmin is checked.
In my case, I was logged in on an account without that privilege.
HTH!
Killing the process ID worked nicely for me.
When running "EXEC sp_who2" Command over a new query window... and filter the results for the "busy" database , Killing the processes with "KILL " command managed to do the trick. After that all worked again.
I know this is an old post but I recently ran into a very similar problem. Unfortunately I wasn't able to use any of the alter database commands because an exclusive lock couldn't be placed. But I was never able to find an open connection to the db. I eventually had to forcefully delete the health state of the database to force it into a restoring state instead of in recovery.
In rare cases (e.g., after a heavy transaction is commited) a running CHECKPOINT system process holding a FILE lock on the database file prevents transition to MULTI_USER mode.
In my scenario, there was no process blocking the database under sp_who2. However, we discovered because the database is much larger than our other databases that pending processes were still running which is why the database under the availability group still displayed as red/offline after we tried to 'resume data'by right clicking the paused database.
To check if you still have processes running just execute this command:
select percent complete from sys.dm_exec_requests
where percent_complete > 0