私はデータベースを復元するために次のコードを使用しています、
void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath)
{
string sRestore =
"USE [master] RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + "' WITH FILE = 1, NOUNLOAD, STATS = 10";
using (SqlConnection con = new SqlConnection(ConnectionString))
{
con.Open();
SqlCommand cmdBackUp = new SqlCommand(sRestore, con);
cmdBackUp.ExecuteNonQuery();
}
}
しかし、以下の例外を受けます
"Exclusive access could not be obtained because the database is in use.
RESTORE DATABASE is terminating abnormally.
Changed database context to 'master'."
どうすれば修正できますか?
復元は、データベースに(ユーザーのほかに)接続がない場合にのみ発生します。 MS SQL Serverですべてのユーザーを開始する簡単な方法は次のとおりです。
ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO
これで、問題なく復元を実行できます。復元が完了したら、必ずマルチユーザーモードに戻してください。
ALTER DATABASE [MyDB] SET Multi_User
GO
したがって、私はデータベースを復元するために以下の方法を書きました、
私は正しい方法ですか?
void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath)
{
using (SqlConnection con = new SqlConnection(ConnectionString))
{
con.Open();
string UseMaster = "USE master";
SqlCommand UseMasterCommand = new SqlCommand(UseMaster, con);
UseMasterCommand.ExecuteNonQuery();
string Alter1 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Single_User WITH Rollback Immediate";
SqlCommand Alter1Cmd = new SqlCommand(Alter1, con);
Alter1Cmd.ExecuteNonQuery();
string Restore = @"RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + @"' WITH FILE = 1, NOUNLOAD, STATS = 10";
SqlCommand RestoreCmd = new SqlCommand(Restore, con);
RestoreCmd.ExecuteNonQuery();
string Alter2 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Multi_User";
SqlCommand Alter2Cmd = new SqlCommand(Alter2, con);
Alter2Cmd.ExecuteNonQuery();
labelReport.Text = "Successful";
}
}
SMO SqlServerオブジェクトのメソッドを使用して、復元を実行する前に、指定したデータベースのすべてのプロセスを強制終了できます。
sqlServer.KillAllProcesses("databaseName");
最善のアプローチ
Alter Database <Db_Name> SET [SINGLE_USER | RESTRICTED_USER]
With ROLLBACK [IMMEDIATE | AFTER 30]
go
--do your job that needs exclusive access
go
--Back to normal mode
Alter Database <Db_Name> SET MULTI_USER
WInn ROLLBACK AFTER nnn-このオプションは、開いているすべてのトランザクションをロールバックしますnnn秒待ってから開いているトランザクションが完了するまで。この例では、開いているトランザクションをロールバックする前にプロセスが30秒待機する必要があることを指定しています。
RESTRICTED_USERを指定すると、db_owner、dbcreator、またはsysadminロールのメンバーのみがデータベースを使用できます。 MULTI_USERは、データベースを通常の動作状態に戻します。
2番目の方法:ssms 2008 R2を使用すると、同じことができます
データベースのプロパティを変更するには、SQL Server/データベースへの他のすべての接続を閉じる必要があります。プロパティを変更して他のすべての接続を閉じてもよろしいですか?はい、もしくは、いいえ
3番目の方法:次のコマンドもすべての接続を閉じます。
ALTER DATABASE [DbName] SET OFFLINE
go
ALTER DATABASE [DbName] SET ONLINE
これで、データベースを復元する準備ができました
詳細( mssqltips:Getting exclusive access to restore SQL Server databases )
データベースへの接続は1つしか確立できません。 -次のコマンドを実行して、データベースへの定期的な接続がどこから行われているかを確認します。
EXEC SP_WHO2
DBName列の下を見て、このリストを確認してください。データベースがリストされている場合は、ProgramNameおよびHostName列をチェックして、誰が接続を試みているかを確認します。
それがサービスや、自動的に再接続してシャットダウンできる他のアプリケーションでない場合は、SPID列の番号をメモして接続を強制終了し、すぐにバックアップを開始します。以下のSPIDを番号のみに置き換えます。
KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
これが正常に完了すると、新しく復元されたデータベースをマルチユーザーモードに戻すことができます。
ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
この問題の理由は自明です(現在開いている/アクティブなデータベースへの接続)が、次を使用してください(Googleでも理解できるようにしてください)、問題ありません。
Alter Database YOURDB
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO
明らかに、YOURDDB
をデータベースの名前に置き換え、それをマスターDBに対して実行します。
ああ、念のために言っておくと、シングルユーザーモードで「スタック」してしまった場合は、元に戻します。
Alter Database YOURDB
SET MULTI_USER With ROLLBACK IMMEDIATE
GO
お役に立てれば。
編集:
this をたどって、接続元を確認することもできます。
データベースに再接続するサービスを実行しているときにこれをテストしました。シングルユーザーモードに設定してから、sp_who2を実行して、1つの接続の送信元を確認し、SPIDをメモする必要があることがわかりました。そのSPIDのkillコマンドと復元を同じトランザクションで実行できます。これが私が使ったシーケンスです:
MASTER ALTER DATABASE DATABASENAME SET SINGLE_USER with ROLLBACK IMMEDIATE GOを使用する
-これにより、データベースへの接続を1つだけ確立できるようになります。 -次のコマンドを実行して、データベースへの定期的な接続がどこから行われているかを確認します。
EXEC SP_WHO2
-DBName列の下を見て、このリストを確認します。データベースがリストされている場合は、ProgramNameおよびHostName列を確認して、接続しようとしているユーザーを確認します。 -サービス、または自動的に再接続してシャットダウンできる他のアプリケーションでない場合は、SPID列の番号をメモして接続を強制終了し、すぐにバックアップを開始します。以下のSPIDを番号のみに置き換えます。
KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\ PATHTO\BACKUP.BAK' GO
-これが正常に完了すると、新しく復元されたデータベースをマルチユーザーモードに戻すことができます。
ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO