37

私はデータベースを復元するために次のコードを使用しています、

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'."

どうすれば修正できますか?

4

6 に答える 6

54

復元は、データベースに(自分以外の)接続がない場合にのみ発生します。MS SQL Serverですべてのユーザーをキックオフする簡単な方法は、次のとおりです。

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

これで、免責で復元を実行できます。復元が完了したら、必ずマルチユーザーモードに戻してください。

ALTER DATABASE [MyDB] SET Multi_User
GO
于 2010-10-28T20:06:26.253 に答える
14

したがって、私はデータベースを復元するために以下のメソッドを作成しました、
私は正しい方法ですか?

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";
    }
}
于 2010-10-29T02:55:13.067 に答える
9

最善のアプローチ

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 
  • WITH ROLLBACK IMMEDIATE-このオプションは、トランザクションが完了するのを待たずに、開いているすべてのトランザクションのロールバックを開始するだけです
  • WITH ROLLBACK AFTER nnn-このオプションは、開いているトランザクションが完了するのをnnn秒待った後、開いているすべてのトランザクションをロールバックします。この例では、開いているトランザクションをロールバックする前に、プロセスが30秒待機するように指定しています。

  • RESTRICTED_USERが指定されている場合、 db_owner、dbcreator、またはsysadminロールのメンバーのみがデータベースを使用できます。MULTI_USERは、データベースを通常の動作状態に戻します。


2番目の方法:ssms 2008 R2を使用すると、同じことができます

  1. データベースプロパティを右クリックします
  2. オプション->状態のヘッダーがある最後のセクションに移動します
  3. SINGLE_USERへのアクセスを制限するを変更します
  4. この種のアクションが他のすべての接続を閉じることを示すこの有用な質問に「はい」と答えてください。エラーを回避するためにここで探しているのはそれだけだと思います。

データベースのプロパティを変更するには、SQLServerはデータベースへの他のすべての接続を閉じる必要があります。プロパティを変更して他のすべての接続を閉じてもよろしいですか?はい、もしくは、いいえ

  1. データベースを復元する
  2. 手順1-4を実行してアクセス制限MULTI_USERに戻します

3番目の方法:次のコマンドもすべての接続を閉じます。

ALTER DATABASE [DbName] SET OFFLINE
go    
ALTER DATABASE [DbName] SET ONLINE

これで、データベースを復元する準備が整いました

詳細(mssqltips:SQL Serverデータベースを復元するための排他的アクセスの取得

于 2012-02-19T10:10:52.873 に答える
8

SMO SqlServerオブジェクトのメソッドを使用して、復元を実行する前に、指定したデータベース上のすべてのプロセスを強制終了できます。

sqlServer.KillAllProcesses("databaseName");
于 2013-07-21T18:25:36.560 に答える
1

この問題の理由は自明です(データベースへの接続は現在開いている/アクティブです)が、以下を使用してください(グーグルでも理解できるので)、問題ありません:

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

明らかに、データベースの名前に置き換えYOURDDBて、マスターDBに対して実行します。

ああ、念のため、シングルユーザーモードで「スタック」すると、元に戻されます。

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

お役に立てれば。

編集:

これに従って、接続元やその他の情報を確認することもできます。

データベースに再接続するサービスを実行しながら、これをテストしました。シングルユーザーモードに設定してから、sp_who2を実行して、1つの接続がどこから来ているかを確認し、SPIDをメモする必要があることがわかりました。そのSPIDに対してkillコマンドを実行し、同じトランザクションで復元を実行すると、実行されるはずです。これが私が使用したシーケンスです:

USE 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

于 2010-10-28T20:03:34.460 に答える
1
  • データベースへの接続は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
    
于 2013-09-10T09:39:07.340 に答える