Kill the SPIDs
Recently ran into a situation where reporting logins were interfering with nightly jobs due to blocking. After several attempts to resolve the blocking through other means, we settled on a pragmatic solution: a stored procedure that disables the login and kills any active sessions for that user.
On the flip side, a separate job re-enables the login at the conclusion of the nightly work.
SET NOCOUNT ON;
DECLARE @rowsToProcess INT;DECLARE @currentRow INT;DECLARE @selectSpid INT;DECLARE @user NVARCHAR(128);DECLARE @killString VARCHAR(50);DECLARE @disableLogin VARCHAR(200);
SET @user = N''; -- add login name
-- disable login to prevent new connectionsSET @disableLogin = 'ALTER LOGIN ' + QUOTENAME(@user) + ' DISABLE;';EXEC (@disableLogin);
40 collapsed lines
-- store active SPIDs for this userDECLARE @spidTable TABLE ( rowid INT NOT NULL PRIMARY KEY IDENTITY(1,1), spid INT, loginname NVARCHAR(128), spid_status VARCHAR(15));
INSERT INTO @spidTable (spid, loginname, spid_status)SELECT spid, loginame, statusFROM sys.sysprocessesWHERE loginame = @user;
SET @rowsToProcess = @@ROWCOUNT;SET @currentRow = 0;
WHILE @currentRow < @rowsToProcessBEGIN SET @currentRow = @currentRow + 1;
SELECT @selectSpid = spid FROM @spidTable WHERE rowid = @currentRow;
SET @killString = 'KILL ' + CONVERT(VARCHAR, @selectSpid);
-- confirm the SPID still belongs to the target user before killing IF EXISTS ( SELECT 1 FROM sys.sysprocesses WHERE spid = @selectSpid AND loginame = @user ) BEGIN PRINT @killString; -- verification step EXEC (@killString); END ELSE PRINT 'No spid to kill';
WAITFOR DELAY '00:00:05'; -- optional delay between killsEND;A few notes:
NVARCHAR(128)is the correct type for SQL login names — the system allows up to 128 characters and supports Unicode.QUOTENAME()around the login name in theALTER LOGINstatement prevents SQL injection if this gets parameterized later.- The verification check before
KILLis intentional — SPIDs can disappear between when you queried them and when you try to kill them. sys.sysprocessesis a legacy compatibility view. For newer environments,sys.dm_exec_sessionsandsys.dm_exec_requestsare preferred.
Key Takeaways
- Disabling a login before killing sessions prevents the user from reconnecting while the cleanup runs.
- Always verify a SPID still exists and belongs to the correct login before killing it — stale SPID data causes errors.
- Use
NVARCHAR(128)for login name storage;VARCHAR(30)will silently truncate long login names. QUOTENAME()is non-optional when building dynamic SQL from user-supplied or variable values.