开发者

Is it possible for a trigger to find the name of the stored procedure that modified data?

There are a few stored procedures that routinely get called by a few different systems to do maintenance on a few tables in our database. Some are automated, some aren't.

One of the tab开发者_开发百科les has a column where the number is sometimes off, and we don't know for sure when or why this is happening. I want to put a trigger on the table so I can see what is being changed and when, but it'd also be helpful to know which procedure initiated the modification.

Is it possible to get the name of the stored procedure from the trigger? If not, is there any other way to tell what caused something to be modified? (I'm not talking about the user either, the name of the user doesn't help in this case).


you can try: CONTEXT_INFO

here is a CONTEXT_INFO usage example:

in every procedure doing the insert/delete/update that you want to track, add this:

DECLARE @string        varchar(128)
       ,@CONTEXT_INFO  varbinary(128)
SET @string=ISNULL(OBJECT_NAME(@@PROCID),'none')
SET @CONTEXT_INFO =cast('Procedure='+@string+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

here is the portion of the trigger to retrieve the value:

DECLARE @string         varchar(128)
       ,@sCONTEXT_INFO  varchar(128)
SELECT @sCONTEXT_INFO=CAST(CONTEXT_INFO() AS VARCHAR) FROM master.dbo.SYSPROCESSES WHERE SPID=@@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


Our system is already using the CONTEXT_INFO variable for another purpose so that is not available. I also tried the DBCC INPUTBUFFER solution which almost worked. The draw back to the inputbuffer is that it returns only the outside calling procedure. Ex: procA calls procB which fires a trigger. The trigger runs DBCC INPUTBUFFER which only shows procA. Since my trigger was looking for procB, this approach failed.

What I have done in the meantime is to create a staging table. Now procA calls procB. procB inserts a line in the staging table then fires the trigger. The trigger checks the staging table and finds the procB entry. Upon return procB deletes its entry from the staging table. It's a shell game but it works. I would be interested in any feedback on this.


I've not tried this but @@PROCID looks like it might return what you want.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜