Cách bỏ cơ sở dữ liệu trong chế độ Single_User


12

Làm thế nào để tôi bỏ một cơ sở dữ liệu hiển thị DatabaseName (Single User)như tên của nó?

Khi tôi cố gắng xóa nó, tôi gặp lỗi sau:

Thay đổi thất bại cho cơ sở dữ liệu 'DatabaseName'. (Microsoft.SqlServer.Smo)

THAY ĐỔI câu lệnh thất bại. (Máy chủ Microsoft SQL, Lỗi: 5064)

Tôi đã cố gắng thực hiện ALTERdưới đây và vẫn có vấn đề tương tự.

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT

Câu trả lời:


23

Nếu bạn định bỏ cơ sở dữ liệu, bạn phải là kết nối duy nhất đến cơ sở dữ liệu đó. Nếu có bất kỳ kết nối nào khác ở đó, bạn không thể bỏ nó. Từ thông báo lỗi (lỗi đó có nghĩa là cơ sở dữ liệu của bạn ở chế độ Single_User nhưng đã có kết nối nên bạn không thể kết nối) giả định của tôi ở đây là bạn đã cố gắng đặt nó ở chế độ Single_User và sau đó cố gắng thực hiện việc thả nhưng bạn đã lấy một kết nối mà bạn không biết hoặc một số quy trình khác có. Thực tế là việc khởi động lại SSMS làm việc cho bạn cho tôi biết có lẽ bạn đã lấy kết nối đó. Vì vậy, đây là cách bạn có thể khắc phục điều đó.

Về mặt logic, bạn phải đưa cơ sở dữ liệu trở lại chế độ multi_user để sau đó bạn có thể đặt lại vào chế độ single_user (nhưng lần này bạn sẽ kiểm soát kết nối duy nhất đó được cho phép và thả cơ sở dữ liệu trước khi có kết nối khác) và sau đó cơ sở dữ liệu của bạn sẽ được đi

Trong mã ở đây là cách bạn cần thực hiện việc này ( nhưng trước tiên hãy đóng các cửa sổ truy vấn được kết nối với cơ sở dữ liệu đó. Khởi động lại SSMS và đảm bảo bạn không chọn cơ sở dữ liệu này trong trình duyệt đối tượng ):

-- 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

Giải pháp này sẽ không hoạt động nếu cơ sở dữ liệu đã ở chế độ Người dùng đơn và bạn cố gắng truy cập nó từ một kết nối khác.
Maxim Paukov

4
Đúng vậy Maxim - Đó là lý do tại sao tôi nói rằng giả định của tôi ở đây dựa trên thông tin được cung cấp và câu trả lời của OP thực sự là kết nối mở có thể thông qua trình thám hiểm đối tượng hoặc cửa sổ truy vấn ... Nếu nó được mở theo cách khác người dùng khác, sau đó bạn sẽ phải tìm thấy một kết nối đã đánh cắp kết nối duy nhất được phép và sau đó hủy phiên - một kết nối và thực hiện theo các bước được nêu ở trên ..
Mike Walsh

13

Nếu bạn cố gắng truy cập cơ sở dữ liệu đã ở chế độ Người dùng đơn, bạn cần đóng tất cả các kết nối với cơ sở dữ liệu trước, nếu không bạn sẽ nhận được thông báo lỗi:

Msg 5064, Cấp 16, Trạng thái 1, Dòng 1 Thay đổi trạng thái hoặc tùy chọn của cơ sở dữ liệu 'DatabaseName' không thể được thực hiện tại thời điểm này. Cơ sở dữ liệu ở chế độ một người dùng và người dùng hiện đang kết nối với nó. Msg 5069, Cấp 16, Trạng thái 1, Dòng 1 Thay đổi câu lệnh ALTER DATABASE không thành công.

Các truy vấn sau đây giết chết các quá trình truy cập vào cơ sở dữ liệu:

-- 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

Sau đó, bạn sẽ có thể đưa cơ sở dữ liệu trở lại chế độ Nhiều người dùng như bình thường:

ALTER DATABASE 'DatabaseName' SET MULTI_USER

2
Đây là một giải pháp rất, rất cồng kềnh và tương đương với một trò chơi bực bội của một kẻ đánh đòn trên một hệ thống bận rộn. Để loại bỏ tất cả người dùng, dễ sử dụng hơn ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATEnhư câu trả lời của Mike cho thấy.
Aaron Bertrand

1
@AaronBertrand Giải pháp của Mike sẽ không hoạt động nếu cơ sở dữ liệu đã ở chế độ Người dùng đơn và bạn cố gắng truy cập nó từ một kết nối khác.
Maxim Paukov

2
Đúng vậy, nếu đó là trường hợp, anh ta sẽ phải tìm các phiên như bạn đã vạch ra. Tuy nhiên, nếu kết nối đặt cơ sở dữ liệu thành single_user là của riêng anh ấy ...
Aaron Bertrand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.