81 votes

Date de la dernière exécution d'une procédure stockée en MS SQL

Nous commençons à avoir beaucoup de procédures stockées dans notre application. Beaucoup d'entre elles sont destinées à des rapports personnalisés, dont beaucoup ne sont plus utilisés. Quelqu'un connaît-il une requête que nous pourrions exécuter sur les vues système dans SQL Server 2005 et qui nous indiquerait la dernière date d'exécution d'une procédure stockée ?

3 votes

Nous avons tous les journaux de bord de nos Sprocs qui ont été appelés. Tous nos Sprocs ont un paramètre pour l'ID de la session, et celui-ci est inclus dans le journal (avec toute erreur soulevée et la durée). Nous sommes à l'aise (jusqu'à présent !) avec l'overhead, et cela nous a aidé à déboguer et à établir des rapports de gestion.

60voto

Pixelated Points 482

Le code ci-dessous devrait faire l'affaire (>= 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  

Edit 1 : Veuillez prendre note des conseils de Jeff Modens ci-dessous.

0 votes

+1 un script très utile, merci, une petite correction, dans la deuxième ligne vous avez oublié un 'e', il devrait être a.last_execution_time ,

1 votes

Merci et +1 pour cela. DMV très utile. Pouvons-nous obtenir les paramètres d'entrée fournis par la procédure de toute façon ?

4 votes

Sympa. Je suppose que par WHERE DB_NAME(ps.database_id) = '' nous devons remplir l'espace vide avec le nom de notre base de données.

38voto

gbn Points 197263

En un mot, non.

Cependant, il y a des choses "agréables" que vous pouvez faire.

  1. Exécutez une trace du profileur avec, par exemple, le nom de la procédure stockée.
  2. Ajouter une ligne à chaque proc (créer un tableau bien sûr)
    • " INSERT dbo.SPCall (What, When) VALUES (OBJECT_NAME(@@PROCID), GETDATE() "
  3. Prolonger 2 avec la durée aussi

Il y a des choses "amusantes" que vous pouvez faire :

  1. Retirez-le, voyez qui appelle.
  2. Supprimer les droits, voir qui appelle
  3. Ajouter RAISERROR ('Warning: pwn3d: call admin', 16, 1) voir qui appelle
  4. Ajouter WAITFOR DELAY '00:01:00' voir qui appelle

Vous voyez le genre. La méthode éprouvée du support informatique "voir qui appelle".

Si les rapports sont des Reporting Services, alors vous pouvez exploiter la base de données RS pour l'exécution du rapport si vous pouvez faire correspondre le code au DataSet du rapport.

Vous ne pouviez pas compter sur les DMV de toute façon, car ils sont réinitialisés lors du redémarrage du serveur SQL. Les caches/verrous de requêtes sont transitoires et ne persistent pas pendant un certain temps.

0 votes

J'ai d'abord utilisé "see who calls" pour trouver des ports supplémentaires sur un contrôleur de terminal.

31voto

Jeff Moden Points 1279

Oh, faites attention maintenant ! Tout ce qui brille n'est PAS de l'or ! Toutes les vues et fonctions "statistiques" de la DG ont un problème pour ce type de chose. Elles ne fonctionnent que sur ce qui est dans le cache et la durée de vie de ce qui est dans le cache peut être mesurée en minutes. Si vous deviez utiliser une telle chose pour déterminer quels PS sont candidats à l'abandon, vous pourriez avoir de gros ennuis lorsque vous supprimez des PS qui ont été utilisés quelques minutes auparavant.

Les extraits suivants sont tirés de Livres en ligne pour les points de vue donnés sur les dm

sys.dm_exec_procedure_stats Renvoie les statistiques de performance agrégées pour les procédures stockées mises en cache. La vue contient une ligne par procédure stockée, et la durée de vie de la ligne est aussi longue que la procédure stockée reste en cache. Lorsqu'une procédure stockée est retirée du cache, la ligne correspondante est éliminée de cette vue.

sys.dm_exec_query_stats La vue contient une ligne par instruction de requête dans le plan mis en cache, et la durée de vie des lignes est liée au plan lui-même. Lorsqu'un plan est retiré du cache, les lignes correspondantes sont éliminées de cette vue.

3 votes

Serait-il donc juste de dire que si une entrée est présente dans la requête proposée par @Pixelated, alors la dernière heure d'exécution est exacte, mais que si une entrée est manquante, vous ne pouvez pas faire d'hypothèses sur sa dernière heure d'exécution ?

8 votes

Je m'excuse pour cette réponse extrêmement tardive. Je n'ai pas été très présent ici ces derniers temps. Ce que vous avez déclaré ci-dessus est correct.

9voto

Naruto Points 563

sys.dm_exec_procedure_stats contient les informations sur les fonctions d'exécution, les contraintes et les procédures, etc. Mais la durée de vie de la ligne a une limite. Dès que le plan d'exécution est retiré du cache, l'entrée disparaît.

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  

Vous obtiendrez ainsi la liste des procédures récemment exécutées.

Si vous voulez vérifier si une procédure stockée particulière a été exécutée récemment

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

7voto

Si vous activez Query Store sur SQL Server 2016 ou plus récent, vous pouvez utiliser la requête suivante pour obtenir la dernière exécution SP. L'historique dépend de la configuration de Query Store.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X