Câu trả lời:
Lý do mà cách tiếp cận mà Adam đề xuất sẽ không hiệu quả là trong thời gian bạn lặp lại các kết nối đang hoạt động, kết nối mới có thể được thiết lập và bạn sẽ bỏ lỡ những kết nối đó. Thay vào đó, bạn có thể sử dụng phương pháp sau không có nhược điểm này:
-- set your current connection to use master otherwise you might get an error
use master
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
--do you stuff here
ALTER DATABASE YourDatabase SET MULTI_USER
Tập lệnh để thực hiện việc này, thay thế 'DB_NAME' bằng cơ sở dữ liệu để hủy tất cả các kết nối tới:
USE master
GO
SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''
Set @DBName = 'DB_NAME'
IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END
and spid <> @@SPID
vào SELECT @sKillConnection
tuyên bố để nó không cố gắng giết kết nối hiện tại của tôi, điều này sẽ tạo ra một thông báo lỗi.
Giết nó và giết nó bằng lửa:
USE master
go
DECLARE @dbname sysname
SET @dbname = 'yourdbname'
DECLARE @spid int
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname)
WHILE @spid IS NOT NULL
BEGIN
EXECUTE ('KILL ' + @spid)
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) AND spid > @spid
END
Sử dụng SQL Management Studio Express:
Trong cây Object Explorer, đi sâu vào phần Quản lý để "Trình giám sát hoạt động" (nếu bạn không thể tìm thấy nó ở đó thì nhấp chuột phải vào máy chủ cơ sở dữ liệu và chọn "Trình giám sát hoạt động"). Mở Trình giám sát hoạt động, bạn có thể xem tất cả thông tin về quy trình. Bạn sẽ có thể tìm thấy các khóa cho cơ sở dữ liệu mà bạn quan tâm và giết các khóa đó, điều này cũng sẽ giết kết nối.
Bạn sẽ có thể đổi tên sau đó.
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [Test]
SET ONLINE
Ngoại tuyến mất một lúc và đôi khi tôi gặp một số vấn đề với điều đó ..
Cách vững chắc nhất theo ý kiến của tôi:
Detach Nhấp chuột phải vào DB -> Nhiệm vụ -> Detach ... kiểm tra "Thả kết nối" Ok
Reattach Nhấp chuột phải vào Cơ sở dữ liệu -> Đính kèm .. Thêm ... -> chọn cơ sở dữ liệu của bạn và thay đổi cột Đính kèm dưới dạng tên cơ sở dữ liệu bạn muốn. Đồng ý
Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'
Declare @query nvarchar(max)
--Select * from #temp
Select @query =STUFF((
select ' ' + KillCommand from #temp
FOR XML PATH('')),1,1,'')
Execute sp_executesql @query
Drop table #temp
sử dụng cơ sở dữ liệu 'chính' và chạy truy vấn này, nó sẽ giết tất cả các kết nối hoạt động từ cơ sở dữ liệu của bạn.
Tôi thường gặp phải lỗi đó khi tôi đang cố gắng khôi phục cơ sở dữ liệu Tôi thường chỉ đi đến ngọn cây trong Management Studio và nhấp chuột phải và khởi động lại máy chủ cơ sở dữ liệu (vì đó là trên máy phát triển, điều này có thể không lý tưởng trong sản xuất ). Đây là đóng tất cả các kết nối cơ sở dữ liệu.
ALTER DATABASE ... SET SINGLE_USER
lệnh trong các câu trả lời khác trả về cùng một lỗi 'không thể nhận được khóa độc quyền').
Trong MS SQL Server Management Studio trên trình thám hiểm đối tượng, nhấp chuột phải vào cơ sở dữ liệu. Trong menu ngữ cảnh theo sau, chọn 'Nhiệm vụ -> Ngoại tuyến'
Một cách tiếp cận "giết nó bằng lửa" là chỉ cần khởi động lại dịch vụ MSSQLSERVER. Tôi thích làm những thứ từ dòng lệnh. Dán chính xác điều này vào CMD sẽ thực hiện: NET STOP MSSQLSERVER & NET START MSSQLSERVER
Hoặc mở "services.msc" và tìm "SQL Server (MSSQLSERVER)" và nhấp chuột phải, chọn "khởi động lại".
Điều này sẽ "chắc chắn, chắc chắn" giết tất cả các kết nối đến TẤT CẢ các cơ sở dữ liệu đang chạy trên trường hợp đó.
(Tôi thích điều này tốt hơn nhiều cách tiếp cận thay đổi và thay đổi lại cấu hình trên máy chủ / cơ sở dữ liệu)
Đây là cách đáng tin cậy loại điều này trong MS SQL Server Management Studio 2008 (cũng có thể hoạt động cho các phiên bản khác):
Tùy chọn làm việc cho tôi trong kịch bản này như sau:
Thử cái này:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
Nhấp chuột phải vào tên cơ sở dữ liệu, nhấp vào Thuộc tính để nhận cửa sổ thuộc tính, Mở tab Tùy chọn và thay đổi thuộc tính "Hạn chế quyền truy cập" từ Nhiều người dùng thành Người dùng đơn. Khi bạn nhấn vào nút OK, nó sẽ nhắc bạn đóng tất cả kết nối đang mở, chọn "Có" và bạn được đặt để đổi tên cơ sở dữ liệu ....
Chúng không hoạt động với tôi (SQL2008 Enterprise), tôi cũng không thể thấy bất kỳ quy trình đang chạy hoặc người dùng nào được kết nối với DB. Khởi động lại máy chủ (Nhấp chuột phải vào Sql Server trong Management Studio và chọn Khởi động lại) cho phép tôi khôi phục DB.
Tôi đang sử dụng SQL Server 2008 R2, DB của tôi đã được đặt cho một người dùng và có một kết nối hạn chế mọi hành động trên cơ sở dữ liệu. Do đó , giải pháp SQLMenace được đề xuất đã phản hồi với lỗi. Đây là một trong những hoạt động trong trường hợp của tôi .
Tôi sử dụng sp_who để lấy danh sách tất cả quá trình trong cơ sở dữ liệu. Điều này là tốt hơn bởi vì bạn có thể muốn xem lại quá trình để giết.
declare @proc table(
SPID bigint,
Status nvarchar(255),
Login nvarchar(255),
HostName nvarchar(255),
BlkBy nvarchar(255),
DBName nvarchar(255),
Command nvarchar(MAX),
CPUTime bigint,
DiskIO bigint,
LastBatch nvarchar(255),
ProgramName nvarchar(255),
SPID2 bigint,
REQUESTID bigint
)
insert into @proc
exec sp_who2
select *, KillCommand = concat('kill ', SPID, ';')
from @proc
Kết quả
Bạn có thể sử dụng lệnh trong cột KillCommand để giết tiến trình bạn muốn.
SPID KillCommand
26 kill 26;
27 kill 27;
28 kill 28;
Bạn có thể sử dụng lệnh SP_Who và hủy tất cả quá trình sử dụng cơ sở dữ liệu của bạn và sau đó đổi tên cơ sở dữ liệu của bạn.