W
wjh_wy
Unregistered / Unconfirmed
GUEST, unregistred user!
怎样解除死锁的存储过程
if exists (select * from sysobjects where id = object_id('dbo.sp_Kill_Process') and sysstat & 0xf = 4)
drop procedure dbo.sp_Kill_Process
GO
CREATE PROCEDURE sp_Kill_Process
AS
BEGIN
declare @lkdbnm varchar(32),@lkdbid smallint,@lkobjid int,@UserDBID smallint,@usrdbnm varchar(32),@User_ID smallint, @grpid smallint, @stmt varchar(255)
/* ===========================================================*/
/* build temp table with processes and their associated locks */
/* ===========================================================*/
select
'FullName' = case when p.spid > 9 then lo.name else 'System' end,
'UserID'= p.uid,
'UName' = ' ',
'ProcessID'= p.spid,
'Status'= p.status,
'DBID' = p.dbid,
'DbName'= d.name,
'Command'= p.cmd,
'Host'= p.hostname,
'Application'= p.program_name,
'Blocking' = case when l.type >= 256 then 100 else 0 end,
'Blockedby'= p.blocked,
'LockType' = l.type,
'LKObjDBID' = l.dbid,
'LKObjDB' = ' ',
'LKObjID' = l.id,
'LKObj' = case when l.id = 0 then
(select name from master..spt_values where number = l.type and type = 'SFL') else ' ' end,
'LockedPage' = l.page,'GroupID' = p.gid,'GName' = ' ','CPUUsage' = p.cpu,
'PhysicalIO' = p.physical_io,'HostProcess' = p.hostprocess
into #LockInfo from master..sysprocesses p, master..syslocks l,master..syslogins lo (nolock),master..sysdatabases d (nolock)
where p.spid = l.spid and p.suid = lo.suid and p.dbid= d.dbid
and d.name = 'CSV_database' --and p.cpu>10000 --and (RTRIM(p.program_name) = '' or (p.program_name like '%CSV%'))
/* ======================= */
/* flag blocking processes */
/* ======================= */
update #LockInfo set Blocking = 1 where ProcessID in (select Blockedby from #LockInfo where Blockedby > 0)
/* =============================================*/
/* get list of locked object IDs */
/* =============================================*/
exec ('declare c1 cursor for select distinct LockedDBName = d.name, LKObjID , LKObjDBID from #LockInfo, master..sysdatabases d
where LKObjDBID = d.dbid and LKObjID > 0 FOR READ ONLY')
open c1
fetch c1 into @lkdbnm, @lkobjid, @lkdbid
while @@fetch_status >= 0
begin
/* set database.owner.name of locked objects in #info */
select @stmt ='Update #LockInfo set LKObj=' + '''' + @lkdbnm + '''' + '+ ''.'' + u.name + ''.'' + o.name' +
',LKObjDB=' + ''''+@lkdbnm + '''' + ' from '+@lkdbnm+'..sysobjects o,'+@lkdbnm+'..sysusers u ' +
'where o.id='+convert(char(10),@lkobjid)+
' and LKObjID=o.id' +
' and u.uid=o.uid and LKObjDBID=' + convert(char,@lkdbid)
exec(@stmt )
/* next please */
fetch c1 into @lkdbnm, @lkobjid, @lkdbid
end
deallocate c1
/* =============================================*/
/* resolve UserID, GroupID for all processes */
/* get a list of each database we need to visit */
/* =============================================*/
exec ('declare c1 cursor for select distinct DBID, DbName from #LockInfo FOR READ ONLY')
open c1
fetch c1 into @UserDBID, @usrdbnm
while @@fetch_status >= 0
begin
/* set user/group in #LockInfo */
select @stmt = 'Update #LockInfo set GName=g.name,UName=u.name from '+@usrdbnm+'..sysusers u,'+
@usrdbnm+'..sysusers g,#LockInfo '+ 'where u.uid=UserID and g.uid=GroupID and DBID=' + convert(char(10),@UserDBID)
exec(@stmt )
/* next please */
fetch c1 into @UserDBID, @usrdbnm
end
deallocate c1
/* ====== return the #LockInfo table ===== */
/*
SELECT
--FullName ,
ProcessID,
Status,
--DName = DbName,
Command,
Host,
Application,
Blockedby,
LockType,
LKObj,
GName = GName,
CPUUsage,
PhysicalIO,
HostProcess,
UName,
Blocking
FROM #LockInfo (nolock) ORDER BY LKObj, ProcessID
*/
declare @KillString char(100),
@ProcessID smallint
declare c2 cursor for select distinct ProcessID from #LockInfo where Blocking = 1 FOR READ ONLY
open c2
fetch c2 into @ProcessID
while @@fetch_status >= 0
begin
select @KillString = 'Kill ' + Convert(char,@ProcessID )
--select @KillString
exec( @KillString )
select @KillString = "master..xp_cmdshell 'echo "
+'"Kill ' + Convert(char(2),@ProcessID )
+' 时间:' + Convert(char,GetDate()) + '">>c:/csv/log/'
+convert(char(4),DATEPART(year,getdate())) + convert(char(2),DATEPART(month,getdate())) + convert(char(2),DATEPART(day,getdate())) + '.txt'
+ " '"
--select @KillString
exec(@KillString)
fetch c2 into @ProcessID
end
deallocate c2
END
GO
---------------------------------------------
要求:
写成一个存储过程,这个存储过程有一个参数,参数是数据库名。
功能:
用户连到这个数据有被死锁的就帮我把它杀了。
---------------------------------------------------------------
希望各位能帮我完成,先谢谢了。
if exists (select * from sysobjects where id = object_id('dbo.sp_Kill_Process') and sysstat & 0xf = 4)
drop procedure dbo.sp_Kill_Process
GO
CREATE PROCEDURE sp_Kill_Process
AS
BEGIN
declare @lkdbnm varchar(32),@lkdbid smallint,@lkobjid int,@UserDBID smallint,@usrdbnm varchar(32),@User_ID smallint, @grpid smallint, @stmt varchar(255)
/* ===========================================================*/
/* build temp table with processes and their associated locks */
/* ===========================================================*/
select
'FullName' = case when p.spid > 9 then lo.name else 'System' end,
'UserID'= p.uid,
'UName' = ' ',
'ProcessID'= p.spid,
'Status'= p.status,
'DBID' = p.dbid,
'DbName'= d.name,
'Command'= p.cmd,
'Host'= p.hostname,
'Application'= p.program_name,
'Blocking' = case when l.type >= 256 then 100 else 0 end,
'Blockedby'= p.blocked,
'LockType' = l.type,
'LKObjDBID' = l.dbid,
'LKObjDB' = ' ',
'LKObjID' = l.id,
'LKObj' = case when l.id = 0 then
(select name from master..spt_values where number = l.type and type = 'SFL') else ' ' end,
'LockedPage' = l.page,'GroupID' = p.gid,'GName' = ' ','CPUUsage' = p.cpu,
'PhysicalIO' = p.physical_io,'HostProcess' = p.hostprocess
into #LockInfo from master..sysprocesses p, master..syslocks l,master..syslogins lo (nolock),master..sysdatabases d (nolock)
where p.spid = l.spid and p.suid = lo.suid and p.dbid= d.dbid
and d.name = 'CSV_database' --and p.cpu>10000 --and (RTRIM(p.program_name) = '' or (p.program_name like '%CSV%'))
/* ======================= */
/* flag blocking processes */
/* ======================= */
update #LockInfo set Blocking = 1 where ProcessID in (select Blockedby from #LockInfo where Blockedby > 0)
/* =============================================*/
/* get list of locked object IDs */
/* =============================================*/
exec ('declare c1 cursor for select distinct LockedDBName = d.name, LKObjID , LKObjDBID from #LockInfo, master..sysdatabases d
where LKObjDBID = d.dbid and LKObjID > 0 FOR READ ONLY')
open c1
fetch c1 into @lkdbnm, @lkobjid, @lkdbid
while @@fetch_status >= 0
begin
/* set database.owner.name of locked objects in #info */
select @stmt ='Update #LockInfo set LKObj=' + '''' + @lkdbnm + '''' + '+ ''.'' + u.name + ''.'' + o.name' +
',LKObjDB=' + ''''+@lkdbnm + '''' + ' from '+@lkdbnm+'..sysobjects o,'+@lkdbnm+'..sysusers u ' +
'where o.id='+convert(char(10),@lkobjid)+
' and LKObjID=o.id' +
' and u.uid=o.uid and LKObjDBID=' + convert(char,@lkdbid)
exec(@stmt )
/* next please */
fetch c1 into @lkdbnm, @lkobjid, @lkdbid
end
deallocate c1
/* =============================================*/
/* resolve UserID, GroupID for all processes */
/* get a list of each database we need to visit */
/* =============================================*/
exec ('declare c1 cursor for select distinct DBID, DbName from #LockInfo FOR READ ONLY')
open c1
fetch c1 into @UserDBID, @usrdbnm
while @@fetch_status >= 0
begin
/* set user/group in #LockInfo */
select @stmt = 'Update #LockInfo set GName=g.name,UName=u.name from '+@usrdbnm+'..sysusers u,'+
@usrdbnm+'..sysusers g,#LockInfo '+ 'where u.uid=UserID and g.uid=GroupID and DBID=' + convert(char(10),@UserDBID)
exec(@stmt )
/* next please */
fetch c1 into @UserDBID, @usrdbnm
end
deallocate c1
/* ====== return the #LockInfo table ===== */
/*
SELECT
--FullName ,
ProcessID,
Status,
--DName = DbName,
Command,
Host,
Application,
Blockedby,
LockType,
LKObj,
GName = GName,
CPUUsage,
PhysicalIO,
HostProcess,
UName,
Blocking
FROM #LockInfo (nolock) ORDER BY LKObj, ProcessID
*/
declare @KillString char(100),
@ProcessID smallint
declare c2 cursor for select distinct ProcessID from #LockInfo where Blocking = 1 FOR READ ONLY
open c2
fetch c2 into @ProcessID
while @@fetch_status >= 0
begin
select @KillString = 'Kill ' + Convert(char,@ProcessID )
--select @KillString
exec( @KillString )
select @KillString = "master..xp_cmdshell 'echo "
+'"Kill ' + Convert(char(2),@ProcessID )
+' 时间:' + Convert(char,GetDate()) + '">>c:/csv/log/'
+convert(char(4),DATEPART(year,getdate())) + convert(char(2),DATEPART(month,getdate())) + convert(char(2),DATEPART(day,getdate())) + '.txt'
+ " '"
--select @KillString
exec(@KillString)
fetch c2 into @ProcessID
end
deallocate c2
END
GO
---------------------------------------------
要求:
写成一个存储过程,这个存储过程有一个参数,参数是数据库名。
功能:
用户连到这个数据有被死锁的就帮我把它杀了。
---------------------------------------------------------------
希望各位能帮我完成,先谢谢了。