0

我正在尝试编写一个报告当前数据库活动的查询。该查询将各种 DMV 链接在一起,例如sys.dm_exec_connectionssys.dm_exec_sessionssys.dm_exec_requests等。该查询还提取通过该sys.dm_exec_sql_text函数运行的实际查询。

(我知道 Activity Monitor 和 SQL Profiler。我需要在查询中收集这些信息,所以这些程序在这里都不相关。)

我们系统中的大部分活动都发生在存储过程和函数中。很高兴在此查询中看到这些过程的名称。

我的问题是:

如何可靠地显示正在执行的存储过程或函数的名称?

我知道该sys.dm_exec_sql_text函数返回一个objectid,并且我可以将它加入objectidsys.objects. 问题是,这台服务器上有多个数据库,而 sys.objects 只适用于当前数据库。我希望这个查询能够显示正在运行的对象名称,无论查询碰巧针对哪个数据库运行。

到目前为止,我唯一的解决方案是使用sp_msforeachdb创建一个临时表,其中包含所有数据库中的所有对象 ID 和名称,并从dm_exec_sql_text函数的结果中加入该表。

临时表方法有更好的解决方案吗?我觉得我错过了什么。

4

2 回答 2

3

我会推荐 Adam Machanic 的优秀sp_WhoISActive。它不会返回确切的对象名称,但会返回以漂亮的可点击形式执行的 sql 命令。

于 2011-02-25T21:01:45.077 回答
1

--我使用以下过程:

使用 [主]
去

创建过程 [dbo].[sp_who3]
作为

    设置无计数

    声明@LoginName varchar(128)
    声明 @AppName varchar(128)

    选择 [SPID] = s.[spid]
        , [CPU] = s.[cpu]
        , [Physical_IO] = s.[physical_io]
        , [封锁] = s.[封锁]
        , [LoginName] = CONVERT([sysname], RTRIM(s.[Loginame]))
        , [数据库] = d.[名称]
        , [AppName] = s.[program_name]
        , [主机名] = s.[主机名]
        , [状态] = s.[状态]
        , [Cmd] = s.[cmd]
        , [最后一批] = s.[last_batch]
        , [杀死命令] = '杀死' + CAST(s.[spid] AS varchar(10))
        , [缓冲区命令] = 'DBCC InputBuffer(' + CAST(s.[spid] AS varchar(10))
                                                         + ')'
    FROM [master].[dbo].[sysprocesses] s WITH(NOLOCK)
    加入 [master].[sys].[databases] d WITH(NOLOCK)
                ON s.[dbid] = d.[database_id]
    WHERE s.[状态] '背景'
        AND s.[spid] @@SPID --@CurrentSpid@
    ORDER BY s.[blocked] DESC, s.[physical_io] DESC, s.[cpu] DESC, CONVERT([sysname], RTRIM(s.[Loginame]))

    开始
        设置事务隔离级别读取未提交

        SELECT [Spid] = er.[session_Id]
        , [ECID] = sp.[ECID]
        , [数据库] = DB_NAME(sp.[dbid])
        , [用户] = [nt_username]
        , [状态] = 呃.[状态]
        , [等待] = [等待类型]
        , [个别查询] = SUBSTRING(qt.[text], er.[statement_start_offset] / 2, (CASE WHEN er.[statement_end_offset] = - 1 THEN LEN(CONVERT(VARCHAR(MAX), qt.[text])) * 2
                            ELSE er.[statement_end_offset] END - er.[statement_start_offset]) / 2)
        , [父查询] = qt.[文本]
        , [程序] = sp.[程序名称]
        , [主机名] = sp.[主机名]
        , [域] = sp.[nt_domain]
        , [开始时间] = 呃。[开始时间]
        FROM [sys].[dm_exec_requests] er WITH(NOLOCK)
        INNER JOIN [sys].[sysprocesses] sp WITH(NOLOCK)
                ON er.[session_id] = sp.[spid]
        交叉应用 [sys].[dm_exec_sql_text](er.[sql_handle]) qt
        WHERE er.[session_Id] > 50 -- 忽略系统 spid。
            AND er.[session_Id] NOT IN (@@SPID) -- 忽略当前语句。
        ORDER BY er.[session_Id], sp.[ECID]
    结尾
去
于 2011-02-25T02:26:41.007 回答