327 votes

script pour supprimer toutes les connexions à une base de données (plus que RESTRICTED_USER ROLLBACK)

J'ai une base de données de développement qui est fréquemment redéployée à partir d'un projet de base de données Visual Studio (via une construction automatique TFS).

Parfois, lorsque je lance ma compilation, j'obtiens cette erreur :

ALTER DATABASE failed because a lock could not be placed on database 'MyDB'. Try again later.  
ALTER DATABASE statement failed.  
Cannot drop database "MyDB" because it is currently in use.  

J'ai essayé ceci :

ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE

mais je ne peux toujours pas supprimer la base de données. (Je pense que la plupart des développeurs ont dbo accès.)

Je peux exécuter manuellement SP_WHO et commencer à tuer les connexions, mais j'ai besoin d'un moyen automatique de le faire dans la construction automatique. (Bien que cette fois-ci ma connexion soit la seule sur la base de données que j'essaie de supprimer).

Existe-t-il un script qui peut supprimer ma base de données indépendamment de la personne connectée ?

842voto

AlexK Points 1486

Mise à jour

Pour MS SQL Server 2012 et supérieur

USE [master];

DECLARE @kill varchar(8000) = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'  
FROM sys.dm_exec_sessions
WHERE database_id  = db_id('MyDB')

EXEC(@kill);

Pour MS SQL Server 2000, 2005, 2008

USE master;

DECLARE @kill varchar(8000); SET @kill = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';'  
FROM master..sysprocesses  
WHERE dbid = db_id('MyDB')

EXEC(@kill);

31 votes

C'est la meilleure réponse des deux ; elle évite de mettre la base de données hors ligne et la réponse acceptée ne fonctionne pas toujours (parfois, il n'est pas possible de tout annuler).

3 votes

Une belle réponse pour l'agrégation kill dans leur ensemble. J'utiliserais un curseur pour tuer chaque processus, ce qui, bien sûr, n'est pas du tout efficace. La technique utilisée dans cette réponse est brillante.

0 votes

Je suis d'accord avec Mark. Cette méthode devrait être la réponse acceptée car elle est beaucoup plus élégante et a moins d'impact sur les bases de données.

149voto

宮本 武蔵 Points 5712
USE master
GO
ALTER DATABASE database_name
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

Réf : http://msdn.microsoft.com/en-us/library/bb522682%28v=sql.105%29.aspx

10 votes

Curieusement, c'était USE master c'était la clé. J'essayais de supprimer la base de données tout en y étant connecté (Duh !). Je vous remercie.

11 votes

Si vous utilisez SET OFFLINE vous devez supprimer manuellement les fichiers db.

8 votes

Ne serait-ce pas alter database YourDatabaseName set SINGLE_USER with rollback immediate serait-elle meilleure ? Si vous le réglez sur OFFLINE (comme l'indique @mattalxndr) les fichiers seront laissés sur le disque, mais avec SINGLE_USER votre connexion restera la seule, et drop database YourDatabaseName supprimera toujours les fichiers.

36voto

Pourya Points 89

Vous pouvez obtenir le script fourni par SSMS en procédant comme suit :

  1. Cliquez avec le bouton droit de la souris sur une base de données dans le SSMS et sélectionnez supprimer.
  2. Dans la boîte de dialogue, cochez la case "Fermer les connexions existantes".
  3. Cliquez sur le bouton script en haut de la boîte de dialogue.

Le script ressemblera à ceci :

USE [master]
GO
ALTER DATABASE [YourDatabaseName] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
DROP DATABASE [YourDatabaseName]
GO

3 votes

Je ne recommanderai pas de prendre la base de données en mode mono-utilisateur pour n'importe quel utilisateur, car cela peut entraîner la perte de la connexion actuelle à certains utilisateurs de l'application et des problèmes inutiles pour trouver ces utilisateurs et les tuer, ou parfois vous devez redémarrer le serveur SQL si les connexions à la base de données sont si fréquentes.

6voto

Sacha Points 21

D'après mon expérience, l'utilisation de SINGLE_USER est utile la plupart du temps, mais il convient d'être prudent : Il m'est arrivé qu'entre le moment où j'ai lancé la commande SINGLE_USER et le moment où elle s'est terminée... un autre "utilisateur" avait apparemment obtenu l'accès SINGLE_USER, et non moi. Si cela se produit, vous allez avoir du mal à récupérer l'accès à la base de données (dans mon cas, c'est un service spécifique fonctionnant pour un logiciel avec des bases de données SQL qui a obtenu l'accès SINGLE_USER avant moi). Ce que je pense être la méthode la plus fiable (je ne peux pas m'en porter garant, mais c'est ce que je vais tester dans les jours à venir), est en fait la suivante :
- arrêter les services susceptibles d'interférer avec votre accès (s'il y en a)
- utiliser le script 'kill' script ci-dessus pour fermer toutes les connexions
- paramétrer la base de données en single_user immédiatement après cela
- puis procéder à la restauration

0 votes

Si la commande SINGLE_USER se trouve dans le même lot que votre commande de restauration (scriptée) - sans être séparée par une instruction GO ! -- alors aucun autre processus ne peut s'emparer de l'accès mono-utilisateur, d'après ce que j'ai pu constater. Cependant, j'ai été pris ce soir parce que mon travail programmé de nuit de set-single-user;restore;set-multi-user a explosé. un autre processus avait un accès exclusif à mon fichier bak (smh) et donc la restauration a échoué, suivie par l'échec de SET MULTI_USER ... ce qui signifie que lorsque j'ai été appelé au milieu de la nuit pour nettoyer le sang, quelqu'un d'autre avait un accès SINGLE_USER et a dû être tué.

-1voto

Binh Truong Points 1

J'ai testé avec succès le code simple suivant

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

2 votes

J'ai eu des problèmes avec set SINGLE_USER alors qu'il y avait déjà une seule connexion active.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X