Obtenir l’accès exclusif à une base dans SQL Server

Quel développeur ou administrateur n’a jamais rencontré une base de données récalcitrante dans SQL Server ?

En l’occurrence j’avais besoin de restaurer une table en environnement de recette à partir d’une sauvegarde de celle de production.

Naturellement, j’utilise SQL Server Management Studio, clic droit sur ma base Tasks > Restore > Database… Je finis la configuration et clique sur OK et là :

Exclusive access could not be obtained because the database is in use.

Pour résoudre ce problème il faut coupler EXEC sp_who2 et KILL de manière à couper toutes les connexions en cours sur la table. Le script ci-dessous permet de le faire

declare @databasename varchar(50) = 'MaBaseDeDonnees'

declare @kill varchar(8000) = '';

select @kill=@kill+'kill '+convert(varchar(5),spid)+';'
from master..sysprocesses
where dbid=db_id(@databasename);
IF @kill = ''
print N'No connection to kill'
ELSE
print N'Exec ' + @kill

exec (@kill);

Ensuite, soit on est sûr qu’aucune connexion ne s’effectuera avant la restauration, soit on est plus pragmatique et on met la table en accès uniquement. Après la restauration, on repasse la table en accès classique.

USE master;
GO
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;

ALTER DATABASE [dbname] SET MULTI_USER;

Le message d’erreur suivant veut dire qu’il y a encore des connexions sur la base. Il faut donc repasser le script precedent.

Alter database failed because a lock could not be placed on database ‘MaBaseDeDonnees’. try again later

Maintenant on dispose de tous les outils pour être serein face à une base récalcitrante.