SQL Server 中存储过程的上次运行日期

Last Run Date on a Stored Procedure in SQL Server

提问人:Jon Edmiston 提问时间:2/28/2009 最后编辑:marc_sJon Edmiston 更新时间:8/3/2023 访问量:170202

问:

我们开始在应用程序中获得大量存储过程。其中许多用于自定义报告,其中许多已不再使用。有谁知道我们可以在 SQL Server 2005 中的系统视图上运行的查询,该查询会告诉我们上次执行存储过程的日期?

sql-服务器

评论

3赞 Kristen 2/28/2009
我们拥有所有被调用的 Sprocs 日志。我们所有的 Sproc 都有一个会话 ID 参数,该参数包含在日志中(连同引发的任何错误和持续时间)。到目前为止,我们对开销感到满意,并且它经常有助于调试/管理报告

答:

39赞 gbn 2/28/2009 #1

简而言之,没有。

但是,您可以做一些“好”的事情。

  1. 使用存储的进程名称运行探查器跟踪
  2. 每个 proc 添加一行(当然创建一个标签)
    • "INSERT dbo.SPCall (What, When) VALUES (OBJECT_NAME(@@PROCID), GETDATE()"
  3. 延长 2 的持续时间

您可以做一些“有趣”的事情:

  1. 删除它,看看谁来电
  2. 删除权限,查看谁来电
  3. 添加,查看谁来电RAISERROR ('Warning: pwn3d: call admin', 16, 1)
  4. 添加,查看谁来电WAITFOR DELAY '00:01:00'

你明白了。久经考验的“看谁来电”的 IT 支持方法。

如果报表是 Reporting Services,则可以挖掘报表运行的 RS 数据库,前提是可以将代码与报表 DataSet 匹配。

无论如何,您都不能依赖 DMV,因为它们会在 SQL Server 重新启动时重置。 查询缓存/锁是暂时性的,不会持续任何时间长度。

评论

0赞 Chris Catignani 5/18/2018
我首先使用“查看谁来电”来查找终端控制器上的额外端口。
0赞 Andrew Steitz 5/18/2023
“看谁打来电话”的方法非常有趣,但最终可能会成为金鹰集团。不要使用常规搜索,否则您可能会获得有关罗切斯特气体和电力或轮状病毒胃肠炎的信息。搜索“城市词典”。
68赞 Pixelated 3/29/2011 #2

下面的代码应该可以解决问题 (>= 2008)

SELECT o.name, 
       ps.last_execution_time 
FROM   sys.dm_exec_procedure_stats ps 
INNER JOIN 
       sys.objects o 
       ON ps.object_id = o.object_id 
WHERE  DB_NAME(ps.database_id) = '' 
ORDER  BY 
       ps.last_execution_time DESC  

编辑 1 : 请注意下面的 Jeff Modens 建议。如果您在此处找到程序,则可以确定它是准确的。如果你不知道,那么你只是不知道 - 你不能断定它没有运行。

评论

0赞 AmmarR 3/12/2013
+1 一个非常有用的脚本,谢谢,一个小更正,在第二行你错过了一个“e”,应该是,a.last_execution_time
1赞 Neeraj Prasad Sharma 5/9/2014
谢谢和+1。非常有用的DMV。无论如何,我们也可以获取过程提供的输入参数吗?
5赞 Baodad 4/9/2016
好。我认为我们应该用数据库的名称填空。WHERE DB_NAME(ps.database_id) = ''
0赞 10/27/2018
它不显示所有存储过程 仅显示上次运行的存储过程
0赞 Divan 8/21/2023
@Baodad 是的,你是对的。您可能还希望添加到“where”子句以查询特定的 SP。and [name] = 'your_SP_name'
31赞 Jeff Moden 11/22/2012 #3

哦,现在要小心!闪光的未必都是金子!对于此类事情,所有“stats”dm 视图和函数都存在问题。它们只对缓存中的内容起作用,缓存中内容的生存期可以以分钟为单位来衡量。如果您要使用这样的东西来确定哪些 SP 是被丢弃的候选者,那么当您删除几分钟前使用的 SP 时,您可能会受到伤害。

以下摘录来自联机丛书,适用于给定的 dm 视图...

sys.dm_exec_procedure_stats

返回缓存存储过程的聚合性能统计信息。视图每个存储过程包含一行,只要存储过程保持缓存状态,该行的生存期就足够了。从缓存中删除存储过程时,将从此视图中删除相应的行。

sys.dm_exec_query_stats

该视图在缓存计划中的每个查询语句都包含一行,并且行的生存期与计划本身相关联。从缓存中删除计划时,将从此视图中删除相应的行。

评论

3赞 Sir Crispalot 6/8/2015
那么,公平地说,如果@Pixelated提供的查询中存在一个条目,那么最后的执行时间是准确的,但如果缺少一个条目,那么你就不能对其最后的执行时间做出任何假设?
8赞 Jeff Moden 10/30/2015
对于极晚的回答,我深表歉意。我最近没怎么来这里。你上面说的是正确的。
2赞 Martin Smith 3/30/2015 #4

这在 2005 年工作正常(如果计划在缓存中)

USE YourDb;

SELECT qt.[text]          AS [SP Name],
       qs.last_execution_time,
       qs.execution_count AS [Execution Count]
FROM   sys.dm_exec_query_stats AS qs
       CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE  qt.dbid = DB_ID()
       AND objectid = OBJECT_ID('YourProc') 
2赞 user5175823 7/31/2015 #5

我用这个:

use YourDB;

SELECT 
    object_name(object_id), 
    last_execution_time, 
    last_elapsed_time, 
    execution_count
FROM   
     sys.dm_exec_procedure_stats ps 
where 
      lower(object_name(object_id)) like 'Appl-Name%'
order by 1
9赞 Naruto 4/4/2017 #6

sys.dm_exec_procedure_stats包含有关执行函数、约束和过程等的信息。但是行的生存期是有限制的,当执行计划从缓存中删除时,该条目就会消失。

Use [yourDatabaseName]
GO
SELECT  
        SCHEMA_NAME(sysobject.schema_id),
        OBJECT_NAME(stats.object_id), 
        stats.last_execution_time
    FROM   
        sys.dm_exec_procedure_stats stats
        INNER JOIN sys.objects sysobject ON sysobject.object_id = stats.object_id 
    WHERE  
        sysobject.type = 'P'
    ORDER BY
           stats.last_execution_time DESC  

这将为您提供最近执行的过程列表。

如果要检查最近是否执行了特定存储过程

SELECT  
    SCHEMA_NAME(sysobject.schema_id),
    OBJECT_NAME(stats.object_id), 
    stats.last_execution_time
FROM   
    sys.dm_exec_procedure_stats stats
    INNER JOIN sys.objects sysobject ON sysobject.object_id = stats.object_id 
WHERE  
    sysobject.type = 'P'
    and (sysobject.object_id = object_id('schemaname.procedurename') 
    OR sysobject.name = 'procedurename')
ORDER BY
       stats.last_execution_time DESC  
8赞 Alexander Sharovarov 3/30/2019 #7

如果在 SQL Server 2016 或更高版本上启用查询存储,则可以使用以下查询来获取上次 SP 执行。历史记录取决于查询存储配置。

SELECT 
      ObjectName = '[' + s.name + '].[' + o.Name  + ']'
    , LastModificationDate  = MAX(o.modify_date)
    , LastExecutionTime     = MAX(q.last_execution_time)
FROM sys.query_store_query q 
    INNER JOIN sys.objects o
        ON q.object_id = o.object_id
    INNER JOIN sys.schemas s
        ON o.schema_id = s.schema_id
WHERE o.type IN ('P')
GROUP BY o.name , + s.name