2010-11-23 18 views
8

Il y a quelques procédures stockées qui sont régulièrement appelées par quelques systèmes différents pour faire la maintenance sur quelques tables dans notre base de données. Certains sont automatisés, d'autres non.Un déclencheur peut-il trouver le nom de la procédure stockée ayant modifié les données?

Une des tables a une colonne où le nombre est parfois éteint, et nous ne savons pas avec certitude quand ou pourquoi cela se produit. Je veux mettre un déclencheur sur la table afin que je puisse voir ce qui est changé et quand, mais il serait également utile de savoir quelle procédure a initié la modification.

Est-il possible d'obtenir le nom de la procédure stockée à partir du déclencheur? Sinon, y a-t-il un autre moyen de dire ce qui a causé quelque chose à modifier? (Je ne parle pas non plus de l'utilisateur, le nom de l'utilisateur n'aide pas dans ce cas).

+0

Je ne pense pas que ce soit possible, parce que peut-être ce n'est pas une procédure stockée qui a couru, il peut avoir été un simple lot. Je peux me tromper, mais je dirais que dans votre cas, vous devriez examiner une sorte de méthode pour obtenir une liste des lots récents qui impliquent une table spécifique, ce qui est essentiellement ce que fait le moniteur. – BeemerGuy

Répondre

3

vous pouvez essayer: CONTEXT_INFO

ici est un exemple d'utilisation de CONTEXT_INFO:

dans toute procédure faisant l'insertion/suppression/mise à jour que vous souhaitez suivre, ajoutez ceci:

DECLARE @string  varchar(128) 
     ,@CONTEXT_INFO varbinary(128) 
SET @string=ISNULL(OBJECT_NAME(@@PROCID),'none') 
SET @CONTEXT_INFO =cast('Procedure='[email protected]+REPLICATE(' ',128) as varbinary(128)) 
SET CONTEXT_INFO @CONTEXT_INFO 

--do insert/delete/update that will fire the trigger 

SET CONTEXT_INFO 0x0 --clears out the CONTEXT_INFO value 

Voici la partie du déclencheur pour récupérer la valeur:

DECLARE @string   varchar(128) 
     ,@sCONTEXT_INFO varchar(128) 
SELECT @sCONTEXT_INFO=CAST(CONTEXT_INFO() AS VARCHAR) FROM master.dbo.SYSPROCESSES WHERE [email protected]@SPID 

IF LEFT(@sCONTEXT_INFO,9)='Procedure' 
BEGIN 
    SET @string=RIGHT(RTRIM(@sCONTEXT_INFO),LEN(RTRIM(@sCONTEXT_INFO))-10) 
END 
ELSE 
BEGIN --optional failure code 
    RAISERROR('string was not specified',16,1) 
    ROLLBACK TRAN 
    RETURN 
END 

..use the @string 
+0

@KM, merci, je vais essayer, mais je ne suis pas sûr si mon équipe serait ravie de passer par et de modifier chaque procédure stockée pour le débogage temporaire: P – Brandon

+0

serait encore plus heureux de ne pas réparer le punaise? les déclencheurs peuvent être une douleur parfois. –

+0

APP_NAME() permet de suivre différents systèmes. – user423430

-4

Je n'ai pas essayé ceci mais @ PROCID semble qu'il pourrait retourner ce que vous voulez.

+4

Je crois qu'une fois que vous êtes dans le code de déclenchement, cela retournera l'ID du déclencheur lui-même. –

+1

correct. @@ procid (ou nom_objet (@@ procid)) est utile en tant que valeur par défaut d'une table pour savoir d'où provient une insertion. – bwperrin

1

Notre système utilise déjà la variable CONTEXT_INFO à d'autres fins, ce qui n'est pas disponible. J'ai également essayé le DBCC INPUTBUFFER solution qui a presque fonctionné. Le retour à l'inputbuffer est qu'il renvoie seulement la procédure d'appel extérieure. Ex: procA appelle procB qui déclenche un trigger. Le déclencheur exécute DBCC INPUTBUFFER qui affiche uniquement procA. Puisque mon déclencheur était à la recherche de procB, cette approche a échoué.

Entre-temps, j'ai créé une table de transfert. ProcA appelle maintenant procB. procB insère une ligne dans la table de transfert puis déclenche le trigger. Le déclencheur vérifie la table de transfert et trouve l'entrée procB. À son retour, procB supprime son entrée de la table de transfert. C'est un jeu de coquille mais ça marche. Je serais intéressé par tout commentaire à ce sujet.