回答:
Adamが提案したアプローチが機能しない理由は、アクティブな接続をループしている間、新しい接続を確立でき、それらを逃してしまうためです。代わりに、この欠点のない次のアプローチを使用できます。
-- 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
オフラインにすると時間がかかり、時々私はいくつかの問題を経験します。
私の意見では最も堅実な方法:
切り離す 右クリック >タスク->デタッチ...「ドロップ接続」を確認します
再接続 右クリックデータベース->添付....追加...- >データベースを選択し、[添付]列を目的のデータベース名に変更します。OK
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
'master'データベースを使用してこのクエリを実行すると、データベースからのアクティブな接続がすべて強制終了されます。
オブジェクトエクスプローラーのMS SQL Server Management Studioで、データベースを右クリックします。次のコンテキストメニューで、[タスク]-> [オフラインにする]を選択します。
もう1つの「火事でそれを殺す」アプローチは、MSSQLSERVERサービスを再起動することです。コマンドラインから何かをするのが好きです。これをCMDに正確に貼り付けると、次のようになります。NETSTOP 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を使用していますが、DBは既にシングルユーザー用に設定されており、データベースへのアクションを制限する接続がありました。したがって、推奨される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;