データベースの名前を変更したいのですが、データベースで「排他ロックを取得できませんでした」というエラーが引き続き発生します。これは、まだアクティブな接続があることを意味します。
名前を変更できるように、データベースへのすべての接続を切断するにはどうすればよいですか?
データベースの名前を変更したいのですが、データベースで「排他ロックを取得できませんでした」というエラーが引き続き発生します。これは、まだアクティブな接続があることを意味します。
名前を変更できるように、データベースへのすべての接続を切断するにはどうすればよいですか?
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
それを殺し、火で殺します:
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
オフラインにするのにはしばらく時間がかかり、それで問題が発生することがあります..
私の意見では最も堅実な方法:
Detach DB を右クリック -> Tasks -> Detach... "Drop Connections" にチェック OK
再 接続 データベースを右クリック -> 接続.. 追加... -> データベースを選択し、[接続先] 列を目的のデータベース名に変更します。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'データベースを使用してこのクエリを実行すると、データベースからすべてのアクティブな接続が強制終了されます。
通常、データベースを復元しようとすると、そのエラーが発生します。通常は、Management Studio のツリーの一番上に移動し、データベース サーバーを右クリックして再起動します (開発マシン上にあるため、これは運用環境では理想的ではない可能性があります)。 )。これにより、すべてのデータベース接続が閉じられます。
MS SQL Server Management Studio 2008 でこの種のことを確実に実行する方法を次に示します (他のバージョンでも機能する可能性があります)。
オブジェクト エクスプローラーの MS SQL Server Management Studio で、データベースを右クリックします。次のコンテキスト メニューで、[タスク] -> [オフラインにする] を選択します。
もう 1 つの "kill it with fire" アプローチは、MSSQLSERVER サービスを再起動することです。コマンドラインから何かをするのが好きです。これを正確に CMD に貼り付けます: NET STOP MSSQLSERVER & NET START MSSQLSERVER
または、「services.msc」を開き、「SQL Server (MSSQLSERVER)」を見つけて右クリックし、「再起動」を選択します。
これにより、そのインスタンスで実行されているすべてのデータベースへのすべての接続が「確実に」強制終了されます。
(サーバー/データベースの構成を変更して元に戻す多くのアプローチよりも、これが好きです)
このシナリオで私のために機能するオプションは次のとおりです。
データベース名を右クリックし、[プロパティ]をクリックしてプロパティウィンドウを取得し、[オプション]タブを開いて、[アクセスの制限]プロパティをマルチユーザーからシングルユーザーに変更します。[OK]ボタンを押すと、開いているすべての接続を閉じるように求められます。[はい]を選択すると、データベースの名前を変更するように設定されます。
これらは私(SQL2008 Enterprise)では機能しませんでした。実行中のプロセスやDBに接続されているユーザーも表示されませんでした。サーバーを再起動すると (Management Studio で Sql Server を右クリックして [再起動] を選択)、DB を復元できました。
これを試して:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
SQL Server 2008 R2 を使用しています。DB は既にシングル ユーザー用に設定されており、データベースでのアクションを制限する接続がありました。したがって、推奨されるSQLMenace のソリューションはエラーで応答しました。これが私の場合に機能したものです。
SP_Who コマンドを使用して、データベースを使用するすべてのプロセスを強制終了し、データベースの名前を変更できます。