Upewnij się, że nie masz zależności, takich jak migawki bazy danych od bazy danych, którą chcesz usunąć. Chociaż komunikat o błędzie wyglądałby inaczej. Czy na pewno nie ma ukrytego procesu łączącego się z bazą danych? Dobrym rozwiązaniem byłoby uruchomienie skryptu, który zabija wszystkie sesje i natychmiast po zmianie nazwy bazy danych na inną nazwę, a następnie upuszczenie bazy danych.
utwórz kursor na podstawie tego wyboru:
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 wewnątrz kursora:
SET @kill_process = 'KILL ' + @spid
EXEC master.dbo.sp_executesql @kill_process
PRINT 'killed spid : '+ @spid
po zamknięciu i zwolnieniu kursora:
sp_dboption 'my_db', 'single user', 'TRUE'
go
sp_renamedb 'my_db', 'my_db_old'
go
DROP DATABASE MY_DB_OLD
Sesja połączona z inną bazą danych może mieć otwartą transakcję, która również wpływa na bazę danych - sp_who2 pokaże tylko jedną bazę danych. Może to być również coś tak prostego jak Object Explorer lub Object Explorer Details otwarte w SSMS, które ponownie pokazywałyby tylko jedną bazę danych w sp_who2.
Nie zawracaj sobie głowy próbą znalezienia odpowiedzialnej sesji; po prostu zabij ich wszystkich za pomocą jednej instrukcji (i upewnij się, że nie jest to twoja kopia SSMS, która jest podłączona, np. inne okno zapytania, Object Explorer itp.):
Teraz będziesz mógł go upuścić i zrobić to za pomocą DDL, a nie interfejsu użytkownika:
źródło
USE master
, to wtedyDROP DATABASE dbname
. Najwyraźniej wszystko, czego potrzeba, to po prostu „użyć” czegoś innego, aby zwolnić db.Jaka jest twoja bieżąca baza danych po wydaniu
DROP
polecenia? Spróbuj tego:Upewnij się także, że jesteś podłączony jako baza danych,
sa
a niedbo
do którejkolwiek z nich, którą chcesz upuścić.źródło
A może po prostu zobaczysz, co robi SSMS, gdy używasz interfejsu użytkownika, ale powiesz mu, aby wydał skrypt dla akcji? Oto, co robi SSMS po kliknięciu prawym przyciskiem myszy DB i wybierz Usuń, a następnie zaznacz pole, aby zamknąć istniejące połączenia:
źródło
Napotykałem tę sytuację wiele razy, a poniżej to, co robię:
Gdy oczywiste metody nie działają ... (tak jak w twojej sytuacji):
Znajdź identyfikator bazy danych z sysdatabases.
Następnie uruchom -
sp_lock
pokaże wszystkie blokady na instancji wraz ze spid i dbid.Zabij pająki za pomocą dbid, który próbujesz wyłączyć lub upuścić.
Chociaż proces ten jest nieco ręczny, można go zautomatyzować w następujący sposób:
źródło
Znalazłem naprawdę prostą odpowiedź na StackOverflow, która zadziałała dla mnie po raz pierwszy:
https://stackoverflow.com/a/7469167/261405
Oto SQL z tej odpowiedzi:
źródło