Відповіді:
Причина того, що підхід, запропонований Адамом , не спрацює, полягає в тому, що за час, коли ви перебираєте активні з'єднання, можна встановити нове, і ви їх пропустите. Ви можете замість цього використати такий підхід, у якого немає цього недоліку:
-- 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
Сценарій для цього, замініть "DB_NAME" на базу даних, щоб знищити всі з'єднання з:
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
заяви, щоб він не намагався вбити моє поточне з'єднання, що породжувало б повідомлення про помилку.
Вбити його та вбити вогнем:
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:
У діалоговому вікні «Об’єкт провідника» виберіть пункт «Керування активністю» («Керування активністю») (якщо ви не можете його знайти, натисніть правою кнопкою миші на сервері баз даних і виберіть «Монітор активності»). Відкривши Монітор активності, ви можете переглянути всю інформацію про процес. Ви маєте змогу знайти блоки для бази даних, яка вас цікавить, і вбити ці блоки, які також вб'ють з'єднання.
Ви повинні мати змогу перейменувати після цього.
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [Test]
SET ONLINE
Займайтеся офлайн займає деякий час, і іноді у мене виникають проблеми з цим.
На мою думку, найбільш солідний спосіб:
Від'єднати Клацніть правою кнопкою миші DB -> Завдання -> Detach ... встановіть прапорець "Скасувати з'єднання" Ок
Знову клацніть правою кнопкою миші Бази даних -> Вкласти .. Додати ... -> виберіть базу даних та змініть стовпчик "Вкласти як" на потрібне ім'я бази даних. Гаразд
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
скористайтеся базовою базою даних та запустіть цей запит, він знищить усі активні з'єднання з вашою базою даних.
Я зазвичай стикаюся з цією помилкою, коли я намагаюся відновити базу даних, я зазвичай просто переходжу до верхівки дерева в студії управління і клацніть правою кнопкою миші та перезавантажте сервер бази даних (оскільки це на машині розробки, це може бути не ідеально у виробництві ). Це закриває всі підключення до бази даних.
ALTER DATABASE ... SET SINGLE_USER
команди в інших відповідях повернули ту саму помилку "не вдалося отримати ексклюзивний замок").
У студії управління MS SQL Server на Explorer Explorer клацніть правою кнопкою миші на базі даних. У наступному контекстному меню виберіть "Завдання -> Зайняти офлайн"
Ще один підхід "вбити вогнем" - це просто перезапустити службу MSSQLSERVER. Мені подобається робити речі з командного рядка. Вставивши це точно в CMD, це вдасться: NET STOP MSSQLSERVER & NET START MSSQLSERVER
Або відкрийте "services.msc" і знайдіть "SQL Server (MSSQLSERVER)" і клацніть правою кнопкою миші, виберіть "перезапустити".
Це "точно, точно" знищить ВСІ з'єднання до ВСІХ баз даних, що працюють у цьому екземплярі.
(Мені це подобається більше, ніж багато підходів, які змінюють і змінюють назад конфігурацію на сервері / базі даних)
Ось як надійно подібні речі в MS SQL Server Management Studio 2008 (можуть працювати і для інших версій):
Варіант, який працює для мене в цьому сценарії, такий:
Спробуйте це:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
Клацніть правою кнопкою миші на ім'я бази даних, натисніть на вікно Властивості, щоб отримати властивість, відкрийте вкладку Параметри та змініть властивість "Обмежити доступ" з "Користувача на багато користувачів" на "Один користувач". Якщо натиснути кнопку ОК, вона запропонує вам закрити все відкрите з'єднання, виберіть "Так" і ви налаштовані на перейменування бази даних ....
Я використовую SQL Server 2008 R2, моя БД вже була встановлена для одного користувача, і було з'єднання, яке обмежувало будь-які дії з базою даних. Таким чином, рекомендоване рішення SQLMenace відповіло помилково. Ось такий, який працював у моєму випадку .
Я використовую sp_who, щоб отримати список усіх процесів у базі даних. Це краще, тому що ви можете переглянути, який процес вбити.
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
Результат
Ви можете використовувати команду в стовпці KillCommand, щоб знищити потрібний процес.
SPID KillCommand
26 kill 26;
27 kill 27;
28 kill 28;
Ви можете використовувати команду SP_Who і вбити весь процес, який використовує вашу базу даних, а потім перейменувати вашу базу даних.