Cara Menjatuhkan Basis Data dalam Mode Single_User

12

Bagaimana cara menjatuhkan basis data yang menunjukkan DatabaseName (Single User)namanya?

Ketika saya mencoba untuk menghapusnya, saya mendapatkan kesalahan berikut:

Alter gagal untuk Database 'DatabaseName'. (Microsoft.SqlServer.Smo)

Pernyataan ALTER DATABASE gagal. (Microsoft SQL Server, Kesalahan: 5064)

Saya mencoba untuk mengeksekusi di ALTERbawah ini dan masih memiliki masalah yang sama.

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT
Prasad Kanaparthi
sumber

Jawaban:

23

Jika Anda akan menjatuhkan database, Anda harus menjadi satu-satunya koneksi ke database itu. Jika ada koneksi lain di sana, Anda tidak dapat menjatuhkannya. Dari pesan kesalahan (kesalahan itu berarti database Anda dalam mode Single_User tetapi sudah ada koneksi sehingga Anda tidak dapat terhubung) asumsi saya di sini adalah bahwa Anda mencoba untuk mengaturnya ke mode Single_User dan kemudian mencoba untuk melakukan drop tetapi Anda baik meraih koneksi yang tidak Anda ketahui, atau beberapa proses lainnya. Fakta bahwa me-restart SSMS bekerja untuk Anda mengatakan kepada saya itu mungkin Anda mengambil koneksi itu. Jadi, inilah cara Anda memperbaikinya.

Secara logis Anda harus meletakkan database kembali ke mode multi_user sehingga Anda kemudian dapat memasukkannya ke mode single_user lagi (tapi kali ini Anda akan mengendalikan koneksi tunggal yang diizinkan dan menjatuhkan database sebelum hal lain terhubung) dan kemudian database Anda akan pergi.

Dalam kode di sini adalah bagaimana Anda perlu melakukan ini ( tetapi pertama-tama tutup jendela permintaan Anda yang terhubung ke database itu. Restart SSMS dan pastikan Anda tidak memilih database ini di browser objek ):

-- Then attempt to take your database to multi_user mode, do this from master
USE MASTER 
GO

ALTER DATABASE myDatabaseName 
SET multi_user WITH ROLLBACK IMMEDIATE
GO

-- Now put it into single_user mode and drop it. Use Rollback Immediate to disconnect any sessions and rollback their transactions. Safe since you are about to drop the DB.
ALTER DATABASE myDatabaseName
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

DROP DATABASE myDatabaseName
GO
Mike Walsh
sumber
Solusi ini tidak akan berfungsi jika database sudah dalam mode Pengguna Tunggal dan Anda mencoba mengaksesnya dari koneksi lain.
Maxim Paukov
4
Itu benar Maxim - Itu sebabnya saya mengatakan bahwa asumsi saya di sini berdasarkan informasi yang diberikan dan jawaban mandiri OPs sebenarnya adalah orang yang memiliki koneksi terbuka mungkin melalui objek explorer atau jendela permintaan ... Jika itu dibuka dengan cara lain oleh beberapa pengguna lain, maka Anda harus menemukan bahwa satu koneksi yang mencuri koneksi tunggal diizinkan dan kemudian membunuh -yaitu- sesi satu koneksi dan ikuti langkah-langkah yang diuraikan di atas ..
Mike Walsh
13

Jika Anda mencoba mengakses database yang sudah dalam mode Pengguna Tunggal, Anda harus menutup semua koneksi ke database terlebih dahulu, jika tidak, Anda akan mendapatkan pesan kesalahan:

Msg 5064, Level 16, State 1, Line 1 Perubahan ke status atau opsi database 'DatabaseName' tidak dapat dibuat saat ini. Basis data dalam mode satu pengguna, dan pengguna saat ini terhubung dengannya. Msg 5069, Level 16, Status 1, Baris 1 Pernyataan ALAT DATABASE gagal.

The query berikut membunuh proses mengakses database:

-- Create the sql to kill the active database connections  
declare @execSql varchar(1000), @databaseName varchar(100)  
-- Set the database name for which to kill the connections  
set @databaseName = 'DatabaseName'  

set @execSql = ''   
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '  
from    master.dbo.sysprocesses  
where   db_name(dbid) = @databaseName  
     and  
     DBID <> 0  
     and  
     spid <> @@spid  
exec(@execSql)
GO

Maka Anda harus dapat membawa database kembali ke mode Multi-User seperti biasa:

ALTER DATABASE 'DatabaseName' SET MULTI_USER
Maxim Paukov
sumber
2
Ini adalah solusi yang sangat, sangat rumit dan setara dengan permainan frustasi dari whack-a-mole pada sistem yang sibuk. Untuk mengusir semua pengguna, lebih mudah digunakan ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATEseperti yang ditunjukkan jawaban Mike.
Aaron Bertrand
1
Solusi @AaronBertrand Mike tidak akan berfungsi jika database sudah dalam mode Pengguna Tunggal dan Anda mencoba mengaksesnya dari koneksi lain.
Maxim Paukov
2
Benar, jika itu masalahnya, ia harus menemukan sesi seperti yang telah Anda uraikan. Namun, jika koneksi yang mengatur database ke single_user adalah miliknya sendiri ...
Aaron Bertrand