SQL Server 2005 データベースへの現在の接続をすべて切断するにはどうすればよいでしょうか?
-
08-06-2019 - |
質問
データベースの名前を変更したいのですが、データベース上で「排他ロックを取得できませんでした」というエラーが表示され続けます。これは、アクティブな接続が存在することを意味します。
データベースの名前を変更できるように、データベースへのすべての接続を強制終了するにはどうすればよいですか?
解決
見る データベースへのすべてのアクティブな接続を強制終了する.
というアプローチがとられる理由は、 アダムが提案した 動作しないのは、アクティブな接続をループしている間に新しい接続が確立され、それらの接続を見逃すことになるためです。私がリンクした記事では、この欠点がない次のアプローチを使用しています。
-- 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
それを殺して、火で殺してください。
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 DB_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
SP_RENAMEDB 'DB_NAME','DB_NAME_NEW'
Go
ALTER DATABASE DB_NAME_NEW SET MULTI_USER -- set back to multi user
GO
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [Test]
SET ONLINE
オフラインにするのには時間がかかり、時々問題が発生することがあります。
私の意見では、最も確実な方法:
切り離すDBを右クリック -> タスク -> 切り離し...「接続ドロップ」OKを確認してください
再接続「データベース」を右クリックし、「接続」をクリックします。追加...-> データベースを選択し、「Attach As」列を希望のデータベース名に変更します。わかりました
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
「マスター」データベースを使用してこのクエリを実行すると、データベースからのアクティブな接続がすべて強制終了されます。
通常、データベースを復元しようとするとこのエラーが発生します。通常は、Management Studio のツリーの最上部に移動し、右クリックしてデータベース サーバーを再起動します (開発マシン上にあるため、運用環境では理想的ではない可能性があります)。 )。これにより、すべてのデータベース接続が閉じられます。
MS SQL Server Management Studio のオブジェクト エクスプローラーで、データベースを右クリックします。続くコンテキストメニューで「タスク -> オフラインにする」を選択します。
もう 1 つの「火をつけて殺す」アプローチは、MSSQLSERVER サービスを再起動することです。私はコマンドラインから何かをするのが好きです。これを CMD に正確に貼り付けると、次のようになります。ネット ストップ MSSQLSERVER および ネット スタート MSSQLSERVER
または、「services.msc」を開いて「SQL Server (MSSQLSERVER)」を見つけて右クリックし、「再起動」を選択します。
これにより、そのインスタンスで実行されているすべてのデータベースへのすべての接続が「確実に、確実に」切断されます。
(サーバー/データベースの構成を変更したり元に戻したりする多くのアプローチよりも、これが好きです)
MS SQL Server Management Studio 2008 でこの種のことを確実に行う方法は次のとおりです (他のバージョンでも機能する可能性があります)。
- オブジェクト エクスプローラー ツリーで、ルート データベース サーバー (緑色の矢印) を右クリックし、[アクティビティ モニター] をクリックします。
- アクティビティ モニターでプロセス タブを開き、「データベース」ドロップダウン メニューを選択し、必要なデータベースでフィルターします。
- オブジェクト エクスプローラーで DB を右クリックし、「タスク -> オフラインにする」タスクを開始します。その間、これをバックグラウンドで実行したままにしておきます...
- できる限り安全にシャットダウンしてください。
- 「プロセス」タブから残りのプロセスをすべて強制終了します。
- DB をオンラインに戻します。
- DBの名前を変更します。
- サービスをオンラインに戻し、新しい DB をポイントします。
このシナリオで機能するオプションは次のとおりです。
- 問題のデータベースに対して「デタッチ」操作を開始します。これにより、DB でのアクションを妨げるアクティブな接続を表示するウィンドウ (SQL 2005 の場合) が開きます。
- アクティブな接続を強制終了し、切断操作をキャンセルします。
- これで、データベースを復元できるようになります。
これを試して:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
データベース名を右クリックし、「プロパティ」をクリックしてプロパティウィンドウを表示し、「オプション」タブを開き、「アクセス制限」プロパティをマルチユーザーからシングルユーザーに変更します。[OK] ボタンをクリックすると、開いている接続をすべて閉じるように求められます。[はい] を選択すると、データベースの名前を変更する設定が完了します。
これらは私にとっては機能しませんでした (SQL2008 Enterprise)。実行中のプロセスや DB に接続されているユーザーも表示されませんでした。サーバーを再起動すると (Management Studio で [SQL Server] を右クリックし、[再起動] を選択します)、DB を復元できました。
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;
SP_Who コマンドを使用して、データベースを使用するすべてのプロセスを強制終了し、データベースの名前を変更できます。