Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 触发器是否可以找到修改数据的存储过程的名称?_Sql Server 2005_Stored Procedures_Triggers - Fatal编程技术网

Sql server 2005 触发器是否可以找到修改数据的存储过程的名称?

Sql server 2005 触发器是否可以找到修改数据的存储过程的名称?,sql-server-2005,stored-procedures,triggers,Sql Server 2005,Stored Procedures,Triggers,有几个存储过程经常被几个不同的系统调用,以对数据库中的几个表进行维护。有些是自动化的,有些不是 其中一个表有一列,其中的数字有时是关闭的,我们不知道何时或为什么会发生这种情况。我想在桌子上放一个触发器,这样我就可以看到什么被改变了,什么时候被改变了,但是知道是哪个过程启动了修改也是很有帮助的 是否可以从触发器获取存储过程的名称?如果没有,有没有其他方法来说明是什么原因导致某些内容被修改?(我也不是说用户,在这种情况下,用户的名称没有帮助)。我没有尝试过这个方法,但是@PROCID看起来可能会返回

有几个存储过程经常被几个不同的系统调用,以对数据库中的几个表进行维护。有些是自动化的,有些不是

其中一个表有一列,其中的数字有时是关闭的,我们不知道何时或为什么会发生这种情况。我想在桌子上放一个触发器,这样我就可以看到什么被改变了,什么时候被改变了,但是知道是哪个过程启动了修改也是很有帮助的


是否可以从触发器获取存储过程的名称?如果没有,有没有其他方法来说明是什么原因导致某些内容被修改?(我也不是说用户,在这种情况下,用户的名称没有帮助)。

我没有尝试过这个方法,但是@PROCID看起来可能会返回您想要的结果。

您可以尝试:
上下文信息

以下是上下文信息使用示例:

在执行要跟踪的插入/删除/更新的每个过程中,添加以下内容:

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
以下是用于检索值的触发器部分:

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

我们的系统已将CONTEXT_INFO变量用于其他用途,因此该变量不可用。我还尝试了几乎有效的方法。inputbuffer的缺点是它只返回外部调用过程。procA调用触发触发器的procB。触发器运行DBCC INPUTBUFFER,它只显示procA。因为我的触发器正在寻找procB,所以这种方法失败了


在此期间,我所做的是创建一个临时表。现在procA调用procB。procB在暂存表中插入一行,然后触发触发器。触发器检查暂存表并找到procB条目。返回时,procB从暂存表中删除其条目。这是一个空壳游戏,但很有效。我对这方面的任何反馈都很感兴趣。

我相信一旦进入触发器代码,就会返回触发器本身的ID。正确@@procid(或对象名称(@@procid))作为表中的列默认值很有用,可以知道插入的来源。我认为这是不可能的,因为它可能不是一个运行的存储过程,它可能是一个简单的批处理。我可能错了,但我想说的是,在你的情况下,你应该研究某种方法来获得最近批次的列表,这些批次涉及特定的表格,这基本上就是监视器所做的。@KM,谢谢,我来试一试,但我不确定我的团队是否会因为我检查并修改每个存储过程以进行临时调试而感到兴奋:不修复bug会更兴奋吗?触发器有时会很痛苦。APP_NAME()有助于跟踪不同的系统。遗憾的是,这是解决SQL Server中缺少任何过程/触发器调用堆栈的最佳方法。甚至甲骨文也有这个!我工作的第三方数据库也到处使用
CONTEXT\u INFO
。我现在能提供的唯一新建议是,对于SS2016,您可以使用
内存\u优化
表将临时调用堆栈信息存储在内存中,或者使用
会话\u上下文
仅跟踪最新的
@@PROCID
热门话题。注意:从SS2014-SP2开始,您还可以使用sys.dm_exec_input_buffer()而不声明表变量并调用动态SQL执行
DBCC INPUTBUFFER