Yanıtlar:
Adam'ın önerdiği yaklaşımın işe yaramamasının nedeni , aktif bağlantılar üzerinde döngü yaptığınız sırada yeni bir bağlantının kurulabileceği ve bunları kaçıracağınızdır. Bunun yerine, bu dezavantajı olmayan aşağıdaki yaklaşımı kullanabilirsiniz:
-- 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
Bunu yapmak için komut dosyası, tüm bağlantıları öldürmek için 'DB_NAME' veritabanını değiştirin:
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
, SELECT @sKillConnection
böylece mevcut bağlantımı öldürmeye çalışmaz, bu da bir hata mesajı oluşturur.
Öldür ve ateşle öldür:
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
SQL Management Studio Express'i kullanma:
Nesne Gezgini ağacında "Etkinlik İzleyicisi" ne Yönetim altında ayrıntıya inin (orada bulamazsanız, veritabanı sunucusuna sağ tıklayın ve "Etkinlik İzleyicisi" ni seçin). Etkinlik Monitörü'nü açarak tüm işlem bilgilerini görüntüleyebilirsiniz. İlgilendiğiniz veritabanı için kilitleri bulabilmeniz ve bağlantıyı öldürecek olan kilitleri öldürebilmeniz gerekir.
Bundan sonra yeniden adlandırabilmelisin.
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [Test]
SET ONLINE
Çevrimdışı ol biraz zaman alıyor ve bazen bununla ilgili bazı sorunlar yaşıyorum.
Bence en sağlam yol:
Ayır Sağ Tıkla DB -> Görevler -> Ayır ... "Bağlantıları Bırak" ı işaretleyin Tamam
Reattach > takın .. ... Ekle - - Sağ Veritabanları tıklayın> veritabanını seçin ve istediğiniz veritabanı adının sütuna Olarak Ekle değiştirin. Tamam
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
'ana' veritabanını kullanın ve bu sorguyu çalıştırın, veritabanınızdaki tüm etkin bağlantıları öldürür.
Genellikle bir veritabanını geri yüklemeye çalışırken bu hatayla karşılaşıyorum Genellikle Management Studio'daki ağacın en üstüne gider ve veritabanı sunucusunu sağ tıklatıp yeniden başlatırım (çünkü bir geliştirme makinesinde, bu üretimde ideal olmayabilir ). Bu, tüm veritabanı bağlantılarını kapatır.
ALTER DATABASE ... SET SINGLE_USER
diğer cevaplardaki komutlar aynı 'özel kilit alınamadı' hatası döndürdü).
Nesne gezginindeki MS SQL Server Management Studio'da veritabanına sağ tıklayın. Aşağıdaki bağlam menüsünde 'Görevler -> Çevrimdışına Al'ı seçin
Başka bir "ateşle öldür" yaklaşımı, MSSQLSERVER hizmetini yeniden başlatmaktır. Komut satırından bir şeyler yapmayı seviyorum. Bunu tam olarak CMD'ye yapıştırmak bunu yapacaktır: NET STOP MSSQLSERVER & NET START MSSQLSERVER
Veya "services.msc" dosyasını açın ve "SQL Server (MSSQLSERVER)" öğesini bulun ve sağ tıklayın, "yeniden başlat" ı seçin.
Bu, "kesin, kesin" o örnekte çalışan TÜM veritabanlarına TÜM bağlantıları kesecektir.
(Bunu sunucu / veritabanındaki yapılandırmayı değiştiren ve değiştiren birçok yaklaşımdan daha iyi seviyorum)
MS SQL Server Management Studio 2008'de bu tür şeylerin nasıl güvenilir bir şekilde yapılacağı aşağıda açıklanmıştır (diğer sürümler için de kullanılabilir):
Bu senaryoda benim için çalışan seçenek aşağıdaki gibidir:
Bunu dene:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
Veritabanı adına sağ tıklayın, özellik penceresini almak için Özellik'e tıklayın, Seçenekler sekmesini açın ve "Erişimi Kısıtla" özelliğini Çok Kullanıcıdan Tek Kullanıcıya değiştirin. Tamam düğmesine bastığınızda, tüm açık bağlantıyı kapatmanızı, "Evet" i seçmenizi ve veritabanını yeniden adlandırmayı seçmeniz istenir.
SQL Server 2008 R2 kullanıyorum, DB'm zaten tek kullanıcı için ayarlanmış ve veritabanındaki herhangi bir eylemi kısıtlayan bir bağlantı vardı. Bu nedenle, önerilen SQLMenace çözümü hatayla yanıt verdi. İşte benim durumumda çalışan bir tane .
Ben veritabanındaki tüm işlemlerin listesini almak için sp_who kullanın. Bu daha iyidir çünkü hangi işlemi öldüreceğinizi gözden geçirmek isteyebilirsiniz.
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
Sonuç
KillCommand sütununda, istediğiniz işlemi öldürmek için komutu kullanabilirsiniz.
SPID KillCommand
26 kill 26;
27 kill 27;
28 kill 28;
SP_Who komutunu kullanabilir ve veritabanınızı kullanan tüm işlemleri öldürebilir ve ardından veritabanınızı yeniden adlandırabilirsiniz.