Wenn ich versuche, eine Datenbank zu löschen, wird die Fehlermeldung "Datenbank" Datenbankname kann nicht gelöscht werden, da sie derzeit verwendet wird "angezeigt. Wenn ich jedoch sp_who2
Ausführe, sind definitiv keine Sitzungen mit dieser Datenbank verbunden. Ich habe auch die Datenbank auf single_user mode with rollback immediate
Gesetzt.
Warum passiert dies?
Stellen Sie sicher, dass Sie keine Abhängigkeiten wie Datenbank-Snapshots von der Datenbank haben, die Sie entfernen möchten. Die Fehlermeldung würde jedoch anders aussehen. Sind Sie sicher, dass es keinen versteckten Prozess gibt, der eine Verbindung zu Ihrer Datenbank herstellt? Ein guter Ansatz wäre, ein Skript auszuführen, das alle Sitzungen beendet und die Datenbank unmittelbar nach dem Umbenennen in einen anderen Namen umbenennt und dann die Datenbank löscht.
erstellen Sie einen Cursor basierend auf dieser Auswahl:
select d.name , convert (smallint, req_spid) As spid
from master.dbo.syslockinfo l,
master.dbo.spt_values v,
master.dbo.spt_values x,
master.dbo.spt_values u,
master.dbo.sysdatabases d
where l.rsc_type = v.number
and v.type = 'LR'
and l.req_status = x.number
and x.type = 'LS'
and l.req_mode + 1 = u.number
and u.type = 'L'
and l.rsc_dbid = d.dbid
and rsc_dbid = (select top 1 dbid from
master..sysdatabases
where name like 'my_db')
problem im Cursor:
SET @kill_process = 'KILL ' + @spid
EXEC master.dbo.sp_executesql @kill_process
PRINT 'killed spid : '+ @spid
nachdem der Cursor geschlossen und freigegeben wurde:
sp_dboption 'my_db', 'single user', 'TRUE'
go
sp_renamedb 'my_db', 'my_db_old'
go
DROP DATABASE MY_DB_OLD
Eine mit einer anderen Datenbank verbundene Sitzung verfügt möglicherweise über eine offene Transaktion, die sich auch auf Ihre Datenbank auswirkt. Sp_who2 zeigt nur eine Datenbank an. Es könnte auch so einfach sein wie Objekt-Explorer oder Objekt-Explorer-Details, die in SSMS geöffnet sind und wiederum nur eine Datenbank in sp_who2 anzeigen.
Versuchen Sie nicht, finden die verantwortliche Sitzung zu finden; Beenden Sie sie einfach alle mit einer Anweisung (und stellen Sie sicher, dass nicht Ihre Kopie von SSMS verbunden ist, z. B. ein anderes Abfragefenster, Objekt-Explorer usw.):
USE master;
GO
ALTER DATABASE dbname SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
Jetzt können Sie es löschen und dies mit DDL tun, nicht mit der Benutzeroberfläche:
DROP DATABASE dbname;
Was ist Ihre aktuelle Datenbank, wenn Sie den Befehl DROP
ausgeben? Versuche dies:
use master
go
drop database mydb
go
Stellen Sie außerdem sicher, dass Sie als sa
und nicht als dbo
in der Datenbank verbunden sind, die Sie löschen möchten.
Wie wäre es, wenn Sie nur sehen, was SSMS tut, wenn Sie die Benutzeroberfläche verwenden, es aber anweisen, ein Skript für die Aktion auszugeben? Folgendes tut SSMS, wenn Sie mit der rechten Maustaste auf die Datenbank klicken und Löschen auswählen und dann das Kontrollkästchen aktivieren, um vorhandene Verbindungen zu schließen:
EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'yourdbname'
GO
USE [master]
GO
ALTER DATABASE [yourdbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
DROP DATABASE [yourdbname]
GO
Ich habe diese Situation viele Male erlebt und im Folgenden ist, was ich tue:
Wenn offensichtliche Methoden nicht funktionieren ..... (genau wie in Ihrer Situation) :
Ermitteln Sie die Datenbank-ID aus sysdatabases.
Führen Sie dann - sp_lock
, das alle Sperren der Instanz zusammen mit spid und dbid anzeigt.
Töte die Spids mit dem dbid, das du offline oder fallen lassen willst.
Obwohl der Prozess etwas manuell ist, kann er wie folgt automatisiert werden:
IF OBJECT_ID('tempdb.dbo.#temp', 'U') IS NOT NULL
DROP TABLE #temp;
create table #temp (spid int
, dbid int
,ObjId bigint
, IndId bigint
,Type varchar(5)
,resource varchar(max)
,Mode varchar(5)
,status varchar(10));
declare @dbid int
select @dbid =DB_ID(db_name())
insert into #temp
exec sp_lock
select * from #temp
where dbid = @dbid
Ich habe auf StackOverflow eine wirklich einfache Antwort gefunden, die beim ersten Mal für mich funktioniert hat:
https://stackoverflow.com/a/7469167/261405
Hier ist die SQL aus dieser Antwort:
DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'YOUR_DABASE_NAME'
DECLARE @SQL varchar(max)
SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId
--Use this to see results
SELECT @SQL
--Uncomment this to run it
--EXEC(@SQL)