用于查询SQL Server中被锁或是更新的表的存储

本文介绍了一个SQL Server的存储过程sp_lock2,用于查询指定进程ID或所有进程的锁信息,并通过创建临时表来组织锁信息的显示。
USE master
 GO
 alter procedure sp_lock2
 @spid1 int = NULL,      /* server process id to check for locks */
 @spid2 int = NULL       /* other process id to check for locks */
 as
 
set nocount on
 /*
 ** Show the locks for both parameters.
 */
 declare @objid int,
    @indid int,
    @dbid int,
    @string Nvarchar(255)
 
CREATE TABLE #locktable
    (
    spid       smallint
    ,loginname nvarchar(20)
    ,hostname  nvarchar(30)
    ,dbid      int
    ,dbname    nvarchar(20)
    ,ObjOwner  nvarchar(128)
    ,ObjId     int
    ,ObjName   nvarchar(128)
    ,IndId     int
    ,IndName   nvarchar(128)
    ,Type      nvarchar(4)
    ,Resource  nvarchar(16)
    ,Mode      nvarchar(8)
    ,Status    nvarchar(5)
    )
 
if @spid1 is not NULL
 begin
    INSERT #locktable
       (
       spid
       ,loginname
       ,hostname
       ,dbid
       ,dbname
       ,ObjOwner
       ,ObjId
       ,ObjName
       ,IndId
       ,IndName
       ,Type
       ,Resource
       ,Mode
       ,Status
       )
    select convert (smallint, l.req_spid)
       ,coalesce(substring (s.loginame, 1, 20),'')
       ,coalesce(substring (s.hostname, 1, 30),'')
       ,l.rsc_dbid
       ,substring (db_name(l.rsc_dbid), 1, 20)
       ,''
       ,l.rsc_objid
       ,''
       ,l.rsc_indid
       ,''
       ,substring (v.name, 1, 4)
       ,substring (l.rsc_text, 1, 16)
       ,substring (u.name, 1, 8)
       ,substring (x.name, 1, 5)
    from master.dbo.syslockinfo l,
       master.dbo.spt_values v,
       master.dbo.spt_values x,
       master.dbo.spt_values u,
       master.dbo.sysprocesses s
    where l.rsc_type = v.number
    and   v.type = 'LR'
    and   l.req_status = x.number
    and   x.type = 'LS'
    and   l.req_mode + 1 = u.number
    and   u.type = 'L'
    and   req_spid in (@spid1, @spid2)
    and   req_spid = s.spid
 end
 /*
 ** No parameters, so show all the locks.
 */
 else
 begin
    INSERT #locktable
       (
       spid
       ,loginname
       ,hostname
       ,dbid
       ,dbname
       ,ObjOwner
       ,ObjId
       ,ObjName
       ,IndId
       ,IndName
       ,Type
       ,Resource
       ,Mode
       ,Status
       )
    select convert (smallint, l.req_spid)
       ,coalesce(substring (s.loginame, 1, 20),'')
       ,coalesce(substring (s.hostname, 1, 30),'')
       ,l.rsc_dbid
       ,substring (db_name(l.rsc_dbid), 1, 20)
       ,''
       ,l.rsc_objid
       ,''
       ,l.rsc_indid
       ,''
       ,substring (v.name, 1, 4)
       ,substring (l.rsc_text, 1, 16)
       ,substring (u.name, 1, 8)
       ,substring (x.name, 1, 5)
    from master.dbo.syslockinfo l,
       master.dbo.spt_values v,
       master.dbo.spt_values x,
       master.dbo.spt_values u,
       master.dbo.sysprocesses s
    where l.rsc_type = v.number
    and   v.type = 'LR'
    and   l.req_status = x.number
    and   x.type = 'LS'
    and   l.req_mode + 1 = u.number
    and   u.type = 'L'
    and   req_spid = s.spid
    order by spid
 END
 DECLARE lock_cursor CURSOR
 FOR SELECT dbid, ObjId, IndId FROM #locktable
   WHERE Type <>'DB' and Type <> 'FIL'
 
OPEN lock_cursor
 FETCH NEXT FROM lock_cursor INTO @dbid, @objid, @indid
 WHILE @@FETCH_STATUS = 0
    BEGIN
 
   SELECT @string =
       'USE ' + db_name(@dbid) + char(13)
       + 'update #locktable set ObjName = name, ObjOwner = USER_NAME(uid)'
       + ' from sysobjects where id = ' + convert(varchar(32),@objid)
       + ' and ObjId = ' + convert(varchar(32),@objid)
       + ' and dbid = ' + convert(varchar(32),@dbid)
 
   EXECUTE (@string)
 
   SELECT @string =
       'USE ' + db_name(@dbid) + char(13)
       + 'update #locktable set IndName = i.name from sysindexes i '
       + ' where i.id = ' + convert(varchar(32),@objid)
       + ' and i.indid = ' + convert(varchar(32),@indid)
       + ' and ObjId = ' + convert(varchar(32),@objid)
       + ' and dbid = ' + convert(varchar(32),@dbid)
       + ' and #locktable.IndId = ' + convert(varchar(32),@indid)
 
   EXECUTE (@string)
 
   FETCH NEXT FROM lock_cursor INTO @dbid, @objid, @indid
    END
 CLOSE lock_cursor
 DEALLOCATE lock_cursor
 
SELECT * FROM #locktable
 return (0)
 -- END sp_lock2
 GO


 

### 如何在 SQL Server 2008 中查询存储过程内的临时数据 在 SQL Server 2008 中,可以通过创建全局临时来实现跨会话的数据共享和访问。然而,在大多数情况下,更常见的是使用局部临时(`#TempTable`),这些格仅限于当前会话内可见并自动删除。 为了从外部查询存储过程中定义的临时内容,可以考虑以下几种方法: #### 方法一:利用全局临时 如果希望让其他进程能够读取由某个特定存储过程产生的中间结果集,则可以在该存储过程中显式声明一个带有两个井号前缀(`##`) 的全局临时。这种方式下,只要数据库连接未断开,任何拥有适当权限的应用程序都可以对该执行 SELECT 操作[^1]。 ```sql CREATE PROCEDURE sp_CreateGlobalTempTable AS BEGIN CREATE TABLE ##GlobalTemp ( ID INT, Name NVARCHAR(50), CreatedAt DATETIME DEFAULT GETDATE() ); -- 插入一些测试数据... END; GO ``` 之后可以从另一个地方通过简单的 `SELECT * FROM ##GlobalTemp;` 来获取此的内容。 需要注意的是,这种方法虽然简单易行,但在多用户环境中可能会引发命名冲突等问题;因此建议谨慎采用,并确保及时清理不再使用的对象以释放资源。 #### 方法二:返回临时作为输出参数 另一种更为推荐的方式是在存储过程结束时将所需的结果集直接返回给调用方,而不是试图保存在一个持久化结构中等待后续检索。这通常涉及到使用 OUTPUT 参数传递整个结果集或将其写入客户端应用程序的工作区内存中处理。 对于较为复杂的情形——比如当需要先加载大量基础资料再经过一系列转换才能得到最终目标集合时——则可借助 #tempdb 数据库下的本地临时完成前期准备工作,最后一步则是把整理好的记录送回至发起请求的一端[^2]。 ```sql ALTER PROCEDURE sp_ProcessDataAndReturnResults @Result OUT VARCHAR(MAX) AS BEGIN IF OBJECT_ID('tempdb..#LocalTemp') IS NOT NULL DROP TABLE #LocalTemp; SELECT * INTO #LocalTemp FROM SomeViewOrComplexJoinQuery; SET @Result = (SELECT TOP 1 ColumnName FOR JSON PATH FROM #LocalTemp); END; GO ``` 这里展示了如何构建一个名为 `sp_ProcessDataAndReturnResults` 的存储过程,它接受一个字符串类型的输出变量用于携带JSON格式化的单条目信息串流。当然实际应用可根据需求调整逻辑细节以及所选传输媒介的形式。 #### 方法三:调试模式查看临时 另外一种情况可能是开发者想要在开发阶段验证某些操作是否按预期工作而尝试即时观察内部状态变化。此时不妨开启SQL Profiler跟踪工具或是启用 Extended Events 功能监听指定事件类别,从而捕获涉及临时的操作语句及其影响范围。不过这类做法主要适用于诊断分析场景而不适合生产环境部署[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值