在很多情况下,往往会要求数据库管理员终止SQL Server中的用户进程,例如在停止某个数据库的运作时,或者还原数据库之前,或者长时间运行活动事务等情况下。数据库管理员通常会使用SQL Server中提供的“KILL”命令来完成任务。
但是,SQL Server提供的“KILL”命令灵活性不够,不能在一次性结束多个会话,一次只能解决掉一个会话。本文将为大家介绍如何创建一个简单的存储过程来实现同时终止多个会话、结束连续的会话和结束连接到数据库的所有会话等功能。
首先,我们在主数据库中创建“KILL2”这个进程,代码如下所示(参考图一)
USE [master] |
begin
print 'Killing '+convert(varchar(100),@startcount)
set @killcmd ='Kill '+convert(varchar(100),@startcount)
exec(@killcmd)
end
else
begin
Print 'Cannot kill the SPID ' +convert(varchar(100),@startcount) + ' because it does not Exist'
end
set @startcount=@startcount + 1
end
end
if CHARINDEX(',',@param) <> 0
begin
set @tempvar =@param
while charindex(',',@tempvar ) <> 0
begin
SET @tempvar2=left(@tempvar,charindex(',',@tempvar)-1)
set @spid=(select spid from master.dbo.sysprocesses where spid=CONVERT(varchar(100),@tempvar2) and spid>50)
if @spid = CONVERT(varchar(100),@tempvar2)
begin
print 'Killing '+CONVERT(varchar(100),@tempvar2)
set @killcmd='Kill '+CONVERT(varchar(100),@tempvar2)
exec (@killcmd)
end
else
begin
Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@tempvar2) + ' because it does not Exist'
end
set @tempvar =REPLACE(@tempvar,left(@tempvar,charindex(',',@tempvar)),'')
end
set @spid=(select spid from master.dbo.sysprocesses where spid=CONVERT(varchar(100),@tempvar) and spid>50)
if @spid = CONVERT(varchar(100),@tempvar)
begin
print 'Killing '+CONVERT(varchar(100),@tempvar)
set @killcmd='Kill '+CONVERT(varchar(100),@tempvar)
exec (@killcmd)
end
else
begin
Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@tempvar) + ' because it does not Exist'
end
end
if CHARINDEX('=',@param2) <>0
begin
print 'Killing all the SPIDs that are connected to the database '+RIGHT(@param2,(len(@param2)-3))
declare dbcursor
cursor forward_only for select SPID from master.dbo.sysprocesses where DB_NAME(dbid) = RIGHT(@param2,(len(@param2)-3))
open dbcursor
fetch dbcursor into @spid
while @@FETCH_STATUS =0
begin
set @spid2=(select spid from master.dbo.sysprocesses where spid=@spid and spid>50)
if @spid = @spid2 begin
print 'Killing '+CONVERT(varchar(100),@spid2)
set @killcmd='Kill '+CONVERT(varchar(100),@spid2)
exec (@killcmd)
end
else begin Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@spid2) + ' because it does not Exist' end fetch dbcursor into @spid end close dbcursor deallocate dbcursor end if CHARINDEX('-',@param)=0 and CHARINDEX(',',@param) = 0 and CHARINDEX('=',@param)=0 begin set @spid=(select spid from master.dbo.sysprocesses where spid=CONVERT(varchar(100),@param) and spid>50) if @spid = CONVERT(varchar(100),@param) begin print 'Killing '+CONVERT(varchar(100),@param) set @killcmd='Kill '+CONVERT(varchar(100),@param) exec (@killcmd) end else begin Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@param) + ' because it does not Exist' end end go --kill2 '51' --go --kill2 '51-56' --go --kill2 '56,57,58,52' --go --kill2 'db=AdventureWorks2008' --kill2 'db=My Database' --go --sp_who |
图一
用法一
现在,我们假设进程ID(SPID)为51、52、53、54、55、57这几个进程(见图二)连接到了SQL Server数据库,而我们只想把进程ID为54、55和57的进程结束掉。
图二
执行以下命令。注意,在这个例子当中还在命令中加入了其他几个SQL Server中不存在的SPID:61和100。
use master go kill2 '54,57,55,61,100' go |
运行结果:
Killing 54 Killing 57 Msg 6104, Level 16, State 1, Line 1 Cannot use KILL to kill your own process. Cannot kill the SPID 55 because it does not Exist Cannot kill the SPID 61 because it does not Exist Cannot kill the SPID 100 because it does not Exist |