web-dev-qa-db-fra.com

Tuez toutes les sessions pour UN utilisateur dans MS SQL

Nous avons donc une mauvaise application externe qui se connecte à la base de données, exécute une procédure stockée et obtient une réponse.

Il ne libère jamais la connexion à la base de données.

J'ai besoin d'un script qui tue toutes les sessions pour un utilisateur ou j'ai besoin d'un script qui tue toutes les sessions qui ont été inactives pendant x heures pour une base de données particulière

Quelqu'un a quelque chose comme ça?

4
J Anderson

Il n'y a pas vraiment de moyen fiable pour épingler des sessions à une base de données spécifique (sysprocesses l'a, mais elle repose sur le contexte de base de données d'une requête active, et dm_exec_sessions a authenticating_database_id, mais cela dépend de la chaîne de connexion, de la base de données par défaut de la connexion, etc.).

Cela dit, cela semble répondre à toutes vos autres exigences, en essayant de tuer toutes les sessions en utilisant app_name, connexion en tant que login_name, et qui n'ont pas émis de demande au cours des 5 dernières heures:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'KILL ' + CONVERT(VARCHAR(11), session_id) + N';'
FROM sys.dm_exec_sessions
  WHERE [program_name] = N'app_name'
  AND login_name = N'login_name'
  AND last_request_start_time < DATEADD(HOUR, -5, SYSDATETIME());

EXEC sys.sp_executesql @sql;

Si l'application ne fait qu'appeler cette procédure stockée et ne fait jamais rien d'autre, vous pouvez peut-être regarder DBCC INPUTBUFFER pour chaque spid, mais cela devient très fastidieux très rapidement.

13
Aaron Bertrand

Aaron, merci - cela m'a amené à trouver une solution légèrement modifiée.

J'ai commenté le login_name car je ne le connais pas au moment de l'exécution. Mettez dans app_name parce que c'est constant. Et changé last_request_start_time à last_request_end_time (Au cas où).

Maintenant, je vais l'empaqueter pour que je puisse l'exécuter en tant que tâche de maintenance.

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'KILL ' + CONVERT(VARCHAR(11), session_id) + N';'
FROM sys.dm_exec_sessions
  WHERE [program_name] = N'program_name'
  --AND login_name = N'login_name'
  AND last_request_end_time < DATEADD(HOUR, -5, SYSDATETIME());

EXEC sys.sp_executesql @sql;
0
J Anderson