J'utilise le code suivant pour restaurer les bases de données,
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();
}
}
mais je reçois une exception ci-dessous
"Exclusive access could not be obtained because the database is in use.
RESTORE DATABASE is terminating abnormally.
Changed database context to 'master'."
Comment puis-je le réparer?
Une restauration ne peut se produire que si la base de données n'a pas de connexion avec elle (à part la vôtre). Le moyen simple sur un serveur MS SQL pour lancer tous les utilisateurs est:
ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO
Maintenant, vous pouvez effectuer votre restauration en toute impunité. Assurez-vous de le remettre en mode multi-utilisateur lorsque vous avez terminé la restauration:
ALTER DATABASE [MyDB] SET Multi_User
GO
J'ai donc écrit la méthode ci-dessous pour restaurer ma base de données,
Suis-je dans le bon sens?
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";
}
}
Vous pouvez utiliser la méthode sur l'objet SMO Sql Server pour tuer tous les processus sur une base de données spécifiée avant d'effectuer une restauration:
sqlServer.KillAllProcesses("databaseName");
La meilleure approche
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
AVEC ROLLBACK APRÈS nnn - cette option annulera toutes les transactions ouvertes après avoir attendu nnn secondes pour que les transactions ouvertes se terminent. Dans notre exemple, nous spécifions que le processus doit attendre 30 secondes avant d'annuler toutes les transactions ouvertes.
Lorsque RESTRICTED_USER est spécifié, seuls les membres des rôles db_owner, dbcreator ou sysadmin peuvent utiliser la base de données. MULTI_USER ramène la base de données à son état de fonctionnement normal.
2ème façon: en utilisant ssms 2008 R2, nous pouvons faire la même chose
Pour modifier les propriétés de la base de données, SQL Server doit fermer toutes les autres connexions à la base de données. Voulez-vous vraiment modifier les propriétés et fermer toutes les autres connexions? Oui ou non
3ème manière: les commandes suivantes fermeront également toutes les connexions.
ALTER DATABASE [DbName] SET OFFLINE
go
ALTER DATABASE [DbName] SET ONLINE
maintenant la base de données est prête pour la restauration
Plus ( mssqltips: Obtenir un accès exclusif pour restaurer les bases de données SQL Server )
une seule connexion à la base de données peut être établie. -Exécutez la commande suivante pour voir d'où proviennent les connexions récurrentes à la base de données.
EXEC SP_WHO2
Vérifiez cette liste, en regardant sous la colonne DBName. Si la base de données est répertoriée, vérifiez la colonne ProgramName et HostName pour voir qui tente de se connecter.
S'il ne s'agit pas d'un service ou d'une autre application qui se reconnecterait automatiquement et qui peut être arrêtée, notez le numéro dans la colonne SPID pour interrompre la connexion et commencez immédiatement la sauvegarde. Remplacez SPID ci-dessous par juste le numéro.
KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
Si cela se termine avec succès, nous pouvons remettre la base de données nouvellement restaurée en mode multi-utilisateur.
ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
La raison de ce problème est évidente (les connexions à la base de données sont actuellement ouvertes/actives), mais utilisez ce qui suit (google aussi pour que vous le compreniez) et ça ira:
Alter Database YOURDB
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO
Évidemment, remplacez YOURDDB
par le nom de votre base de données et exécutez-le sur la base de données master.
Oh, et juste au cas où, si vous le bloquiez en mode mono-utilisateur, cela l'annulerait:
Alter Database YOURDB
SET MULTI_USER With ROLLBACK IMMEDIATE
GO
J'espère que cela t'aides.
ÉDITER:
Vous pouvez également suivre this , pour voir d'où viennent les connexions et d'autres informations:
J'ai testé cela lors de l'exécution de services qui se reconnecteraient à la base de données. J'ai constaté que vous deviez définir le mode mono-utilisateur, puis exécuter sp_who2 pour voir d'où provenait la connexion et noter le SPID. Vous pouvez exécuter la commande kill pour ce SPID et la restauration dans la même transaction, et elle doit être exécutée. Voici la séquence que j'ai utilisée:
UTILISER MASTER ALTER DATABASE DATABASENAME SET SINGLE_USER AVEC ROLLBACK IMMEDIATE GO
-Cela fera en sorte qu'une seule connexion à la base de données puisse être établie. -Exécutez la commande suivante pour voir d'où proviennent les connexions récurrentes à la base de données.
EXEC SP_WHO2
-Vérifiez cette liste, en regardant sous la colonne DBName. Si la base de données est répertoriée, vérifiez la colonne ProgramName et HostName pour voir qui tente de se connecter. -Si ce n'est pas un service ou une autre application qui se reconnecterait automatiquement et qui peut être arrêtée, notez le numéro dans la colonne SPID pour interrompre la connexion et commencez immédiatement la sauvegarde. Remplacez SPID ci-dessous avec juste le numéro.
KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
-Si cela se termine avec succès, nous pouvons remettre la base de données nouvellement restaurée en mode multi-utilisateur.
ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO