Single_Userモードでデータベースを削除する方法


12

DatabaseName (Single User)名前として表示されているデータベースを削除するにはどうすればよいですか?

削除しようとすると、次のエラーが表示されます。

データベース 'DatabaseName'の変更に失敗しました。(Microsoft.SqlServer.Smo)

ALTER DATABASEステートメントが失敗しました。(Microsoft SQL Server、エラー:5064)

ALTER以下を実行しようとしましたが、まだ同じ問題があります。

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT

回答:


23

データベースを削除する場合は、そのデータベースへの唯一の接続である必要があります。他の接続が存在する場合は、ドロップできません。エラーメッセージから(このエラーはデータベースがSingle_Userモードになっているが、すでに接続されているので接続できないことを意味します)ここでの私の仮定は、それをSingle_Userモードに設定しようとした後、ドロップしようとしたが知らない接続、または他のプロセスが持っている接続を取得しました。SSMSの再起動があなたのために働いたという事実は、おそらくあなたがその接続をつかんでいたことを教えてくれます。だからここにあなたがそれを修正する方法があります。

論理的にデータベースをmulti_userモードに戻して、single_userモードに戻す必要があります(ただし、今回は許可された単一の接続を制御し、他の何かが接続する前にデータベースを削除します)。行って

これを行うには、次のコードを使用します(ただし、最初にそのデータベースに接続されているクエリウィンドウを閉じます。SSMSを再起動し、オブジェクトブラウザでこのデータベースを選択しないようにします)。

-- Then attempt to take your database to multi_user mode, do this from master
USE MASTER 
GO

ALTER DATABASE myDatabaseName 
SET multi_user WITH ROLLBACK IMMEDIATE
GO

-- Now put it into single_user mode and drop it. Use Rollback Immediate to disconnect any sessions and rollback their transactions. Safe since you are about to drop the DB.
ALTER DATABASE myDatabaseName
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

DROP DATABASE myDatabaseName
GO

このソリューションは、データベースがすでにシングルユーザーモードになっていて、他の接続からアクセスしようとすると機能しません。
マキシムパウコフ

4
それが正しいマキシムです-だから、ここで提供された情報とOPsの自己回答に基づいた私の仮定は、おそらくオブジェクトエクスプローラまたはクエリウィンドウを介して開いた接続を持つものだと言いました...他のユーザーは、許可された単一の接続を盗んだ1つの接続を見つけてから、その接続のセッションを強制終了し、上記の手順に従う必要があります。
Mike Walsh

13

既にシングルユーザーモードになっているデータベースにアクセスしようとすると、最初にデータベースへのすべての接続を閉じる必要があります。そうしないと、エラーメッセージが表示されます。

メッセージ5064、レベル16、状態1、行1データベース 'DatabaseName'の状態またはオプションの変更は、現時点ではできません。データベースはシングルユーザーモードであり、ユーザーは現在データベースに接続しています。メッセージ5069、レベル16、状態1、行1のALTER DATABASEステートメントが失敗しました。

次のクエリは、データベースにアクセスしているプロセスを強制終了します。

-- Create the sql to kill the active database connections  
declare @execSql varchar(1000), @databaseName varchar(100)  
-- Set the database name for which to kill the connections  
set @databaseName = 'DatabaseName'  

set @execSql = ''   
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '  
from    master.dbo.sysprocesses  
where   db_name(dbid) = @databaseName  
     and  
     DBID <> 0  
     and  
     spid <> @@spid  
exec(@execSql)
GO

その後、通常どおりデータベースをマルチユーザーモードに戻すことができるはずです。

ALTER DATABASE 'DatabaseName' SET MULTI_USER

2
これは非常に面倒なソリューションであり、忙しいシステムでモグラを叩くというイライラするゲームに相当します。すべてのユーザーを追い出すためにALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE、マイクの答えが示すように、はるかに使いやすくなっています。
アーロンバートランド

1
@AaronBertrand Mikeのソリューションは、データベースが既にシングルユーザーモードであり、他の接続からアクセスしようとすると機能しません。
マキシムパウコフ

2
そうです、もしそうなら、彼はあなたが概説したようにセッションを見つけなければなりません。しかし、SINGLE_USERにデータベースを設定し、接続が...彼自身である場合
アーロン・ベルトラン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.