Datum der letzten Ausführung einer gespeicherten Prozedur in SQL Server

77

Wir fangen an, viele gespeicherte Prozeduren in unsere Anwendung aufzunehmen. Viele von ihnen sind für benutzerdefinierte Berichte bestimmt, von denen viele nicht mehr verwendet werden. Kennt jemand eine Abfrage, die wir in den Systemansichten in SQL Server 2005 ausführen könnten und die uns das letzte Datum mitteilt, an dem eine gespeicherte Prozedur ausgeführt wurde?

Jon Edmiston
quelle
2
Wir haben alle unsere Sprocs-Protokolle, die sie aufgerufen haben. Alle unsere Sprocs haben einen Parameter für die Sitzungs-ID, der im Protokoll enthalten ist (zusammen mit allen Fehlern und der Dauer). Wir haben uns (bisher!) Mit Overhead wohlgefühlt und es hat oft beim Debuggen / Management-Reporting geholfen
Kristen

Antworten:

35

Kurz gesagt, nein.

Es gibt jedoch "schöne" Dinge, die Sie tun können.

  1. Führen Sie eine Profiler-Ablaufverfolgung mit beispielsweise dem gespeicherten Prozessnamen aus
  2. Fügen Sie jedem Prozess eine Zeile hinzu (erstellen Sie natürlich eine Tabelle)
    • " INSERT dbo.SPCall (What, When) VALUES (OBJECT_NAME(@@PROCID), GETDATE()"
  3. Erweitern Sie 2 auch mit der Dauer

Es gibt "lustige" Dinge, die Sie tun können:

  1. Entfernen Sie es, sehen Sie, wer anruft
  2. Rechte entfernen, sehen, wer anruft
  3. Hinzufügen RAISERROR ('Warning: pwn3d: call admin', 16, 1), sehen, wer anruft
  4. Hinzufügen WAITFOR DELAY '00:01:00', sehen, wer anruft

Du hast die Idee. Die bewährte Methode des IT-Supports "Sehen, wer anruft".

Wenn es sich bei den Berichten um Reporting Services handelt, können Sie die RS-Datenbank für die Berichtsausführungen durchsuchen, wenn Sie den Code mit dem Report DataSet abgleichen können.

Sie können sich sowieso nicht auf DMVs verlassen, da diese beim Neustart von SQL Server zurückgesetzt werden. Abfrage-Cache / Sperren sind vorübergehend und bleiben nicht für längere Zeit bestehen.

gbn
quelle
Ich habe zuerst "sehen, wer anruft" verwendet, um zusätzliche Ports auf einem Terminal-Controller zu finden.
Chris Catignani
50

Der folgende Code sollte den Trick machen (> = 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  

Bearbeiten 1: Bitte beachten Sie die folgenden Hinweise von Jeff Modens. Wenn Sie hier ein Verfahren finden, können Sie sicher sein, dass es korrekt ist. Wenn Sie dies nicht tun, wissen Sie es einfach nicht - Sie können nicht schließen, dass es nicht ausgeführt wird.

Pixeliert
quelle
+1 ein sehr nützliches Skript, danke, eine kleine Korrektur, in der zweiten Zeile hast du ein 'e' verpasst, es sollte sein a.last_execution_time,
AmmarR
1
Danke und +1 dafür. sehr nützliche DMV. Können wir auch die von der Prozedur bereitgestellten Eingabeparameter erhalten?
Neeraj Prasad Sharma
3
Nett. Ich gehe davon aus, dass WHERE DB_NAME(ps.database_id) = ''wir die Lücke mit dem Namen unserer Datenbank ausfüllen sollten.
Baodad
Es werden nicht alle gespeicherten Prozeduren
29

Oh, sei jetzt vorsichtig! Nicht alles was glänzt ist Gold! Alle "Statistik" -DM-Ansichten und -Funktionen haben ein Problem für diese Art von Dingen. Sie arbeiten nur mit dem, was sich im Cache befindet, und die Lebensdauer des im Cache befindlichen Objekts kann in Minuten gemessen werden. Wenn Sie so etwas verwenden, um festzustellen, welche SPs Kandidaten für das Löschen sind, könnten Sie in eine Welt voller Verletzungen geraten, wenn Sie SPs löschen, die vor wenigen Minuten verwendet wurden.

Die folgenden Auszüge stammen aus Books Online für die angegebenen dm-Ansichten…

sys.dm_exec_procedure_stats Gibt aggregierte Leistungsstatistiken für zwischengespeicherte gespeicherte Prozeduren zurück. Die Ansicht enthält eine Zeile pro gespeicherter Prozedur, und die Lebensdauer der Zeile ist so lange, wie die gespeicherte Prozedur zwischengespeichert bleibt. Wenn eine gespeicherte Prozedur aus dem Cache entfernt wird, wird die entsprechende Zeile aus dieser Ansicht entfernt.

sys.dm_exec_query_stats Die Ansicht enthält eine Zeile pro Abfrageanweisung im zwischengespeicherten Plan, und die Lebensdauer der Zeilen ist an den Plan selbst gebunden. Wenn ein Plan aus dem Cache entfernt wird, werden die entsprechenden Zeilen aus dieser Ansicht entfernt.

Jeff Moden
quelle
3
Wäre es also fair zu sagen, dass wenn ein Eintrag in der von @Pixelated angebotenen Abfrage vorhanden ist, die letzte Ausführungszeit korrekt ist, aber wenn ein Eintrag fehlt, können Sie keine Annahmen über seine letzte Ausführungszeit treffen?
Sir Crispalot
6
Ich entschuldige mich für die extrem späte Antwort. Ich war in letzter Zeit nicht viel hier. Was Sie oben angegeben haben, ist richtig.
Jeff Moden
8

sys.dm_exec_procedure_stats enthält Informationen zu den Ausführungsfunktionen, Einschränkungen und Prozeduren usw. Die Lebensdauer der Zeile ist jedoch begrenzt. Sobald der Ausführungsplan aus dem Cache entfernt wird, verschwindet der Eintrag.

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  

Dadurch erhalten Sie eine Liste der zuletzt ausgeführten Prozeduren.

Wenn Sie überprüfen möchten, ob eine bestimmte gespeicherte Prozedur kürzlich ausgeführt wurde

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  
Naruto
quelle
4

Wenn Sie den Abfragespeicher unter SQL Server 2016 oder höher aktivieren, können Sie die folgende Abfrage verwenden, um die letzte SP-Ausführung abzurufen. Der Verlauf hängt von der Konfiguration des Abfragespeichers ab.

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 
Alexander Sharovarov
quelle
1

Dies funktioniert gut ab 2005 (wenn sich der Plan im Cache befindet)

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') 
Martin Smith
quelle
1

Ich benutze das:

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
user5175823
quelle