IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID('dbo.expunge_users') AND sysstat & 0xf = 4) DROP PROCEDURE dbo.expunge_users GO CREATE PROCEDURE expunge_users @dbName VARCHAR(30) = ' ', @target VARCHAR(30) = ' ', @targetPassword VARCHAR(30) = ' ', @saPassword VARCHAR(30) = ' ', @path VARCHAR(50) = ' ', @debug VARCHAR(5) = 'false' AS DECLARE @bail SMALLINT, @CMD VARCHAR(255), @CMDstatus INT, @myName VARCHAR(30), @spidToKill VARCHAR(5) /* Procedure expunge_users will attempt to remove all users from a database. Misbehaved code that leaves zombies will prevent the zombie spid from stopping (because its not really active). Long running atomic processes like a huge insert or update may require more time to end than a WAITING COMMAND spid. */ IF (@dbName <> ' ') AND (@target <> ' ') AND (@path <> ' ') BEGIN SELECT @myName = 'admin.expunge_users' /* If every one is not being killed, increase the @bail threshold */ SELECT @bail = 10 WHILE (@bail > 0) BEGIN DELETE messenger where spid = @@SPID SELECT @CMD = "SELECT max(spid) FROM master..sysprocesses " + "WHERE dbid = (SELECT dbid FROM master..sysdatabases " + "WHERE name = '" + @dbName + "')" SELECT @CMD = 'isql -Usa -P' + @targetPassword + ' -S' + @target + ' -dmaster -Q"' + @CMD + '" -o' + @path + '\userCount.txt' EXEC @CMDstatus = dispatch @CMD, @myName, @debug IF (@CMDstatus <> 0) return @CMDstatus EXEC hold_semaphore 'textreader' TRUNCATE TABLE textreader SELECT @CMD = 'bcp admin..textreader in ' + @path + '\userCount.txt -c -Usa -P' + @saPassword + ' -S' + @@SERVERNAME EXEC @CMDstatus = dispatch @CMD, @myName, @debug IF (@CMDstatus <> 0) return @CMDstatus INSERT messenger SELECT @@SPID, text from textreader TRUNCATE TABLE textreader SELECT @CMD = 'isql -Usa -P' + @targetPassword + ' -S' + @target + ' -dmaster -Q"master..xp_cmdshell ' + "'del " + @path + "\userCount.txt'" + '"' EXEC @CMDstatus = dispatch @CMD, @myName, @debug IF (@CMDstatus <> 0) return @CMDstatus INSERT messenger SELECT @@SPID, RTRIM(LTRIM(text)) FROM textreader TRUNCATE TABLE textreader EXEC release_semaphore 'textreader' SELECT @spidToKill = (SELECT min(info) FROM messenger WHERE spid = @@SPID AND info <> " " AND info NOT LIKE "---%" AND info NOT LIKE "%affected)%") IF (SELECT ISNUMERIC(@spidToKill))= 0 SELECT @bail = -1 ELSE BEGIN IF (@target = @@SERVERNAME) AND (CONVERT(VARCHAR(5), @@SPID) = @spidToKill) BEGIN SELECT @CMD = 'Cannot load database ' + @dbName + ' on ' + @target + '. This process is running in the database.' EXEC @CMDstatus = dispatch @CMD, @myName, @debug RETURN @CMDStatus END SELECT @CMD = "kill " + @spidToKill SELECT @CMD = 'isql -Usa -P' + @targetPassword + ' -S' + @target + ' -dmaster -Q"' + @CMD + '"' EXEC @CMDstatus = dispatch @CMD, @myName, @debug IF (@CMDstatus <> 0) return @CMDstatus IF @bail = 0 BEGIN SELECT @CMD = 'There are active users in ' + @dbName + ' on ' + @target + ' that cannot be disconnected at this time.' EXEC @CMDstatus = dispatch @CMD, @myName, @debug IF (@CMDstatus <> 0) return @CMDstatus END SELECT @bail = @bail - 1 END END DELETE messenger where spid = @@SPID RETURN END ELSE BEGIN PRINT " usage: expunge_users [@dbName = <database name>, ]" PRINT " [@target = <target SQL Server>, ]" PRINT " [@targetPassword = <target sa password>,]" PRINT " [@saPassword = <admin sa password>, ]" PRINT " [@path = <output file location>, ]" PRINT " [@debug = <debug - default=false> ]" RETURN 1 END GO