Answers:
是的,可以使用@@ procid系统函数和更好的OBJECT_NAME(@@ PROCID)来标识正在运行的代码,以使其具有完整的名称。
定义:“返回当前Transact-SQL模块的对象标识符(ID)。Transact-SQL模块可以是存储过程,用户定义的函数或触发器。@@ PROCID不能在CLR模块或in-处理数据访问提供程序。”
你可以在这里阅读。
另一个选择是检查当前spid的sql计划并将该信息保存在日志表中。每个过程中用于保存审核数据的示例查询为:
select sp.hostname, sp.program_name, sp.loginame,
st.text as query_text
from sysprocesses sp
cross apply sys.dm_exec_sql_text(sp.sql_handle) as st
where sp.spid = @@spid
也许那里有太多细节。.但是我相信你明白了。
第三种选择是将context_info信息用于当前SP的会话。并将与每个过程一起保存的上下文信息关联到某个地方。例如,在procedure1中,您为上下文编写了111;在procedure2中,您编写了222 ..,依此类推。
您可以在此SO问题中阅读有关context_info的更多信息。
OBJECT_NAME(@@PROCID)
返回触发器名称,而不是调用proc。
我也想这样做。感谢您的回答。当我还在这里时,我将发布测试以节省其他人的时间:)
CREATE TABLE Test ( TestID INT )
GO
CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS
SELECT CAST(CONTEXT_INFO() AS NVARCHAR(128));
GO
CREATE PROCEDURE usp_ProcIDTest
AS
DECLARE @ProcedureName VARBINARY(MAX) = CAST(OBJECT_NAME(@@PROCID) AS VARBINARY(MAX))
SET CONTEXT_INFO @ProcedureName
INSERT INTO Test ( TestID ) VALUES ( 1 )
GO
EXEC usp_ProcIDTest
GO
DROP TABLE Test
GO
XEvents提供了另一种获取T-SQL堆栈的方法,尽管SQL Server 2008可能不支持使用的事件类型。该解决方案包括触发器,错误和XEvent会话。我以吉姆·布朗(Jim Brown)的例子来说明它的工作方式。
首先,我测试了SQL Server 2016 SP2CU2 Dev Edition的解决方案。SQL Server 2008支持某些EXevent,但是我没有任何实例,因此无法对其进行测试。
想法是在虚拟try-catch块中生成用户错误,然后使用tsql_stack
操作在XEvent会话中捕获错误。SQLSERVER.error_reported
XEvent类型可以捕获所有错误,即使try-catch块可以捕获它们。最后,sys.dm_exec_sql_text
从提供操作的查询句柄中提取T-SQL查询tsql_stack
。
下面显示了我开发的Jim Brown答案中的一个示例。触发器会引发错误,提示文字为“抓住我”。XEvent会话仅使用“ catch me”之类的文本捕获错误。
CREATE TABLE Test ( TestID INT )
GO
CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS
BEGIN TRY
SET XACT_ABORT OFF; -- REALLY IMPORTANT!
/* make an catching a great deal more interesting */
DECLARE @TestID NVARCHAR(MAX) ;
SELECT TOP (1) @TestID = CAST(ins.TestID AS NVARCHAR(MAX)) FROM inserted AS ins ;
RAISERROR (N'catch_me TestID = "%s"' , 11 , 0 , @TestID) ;
END TRY BEGIN CATCH /* NOTHING TO DO */ END CATCH
GO
CREATE PROCEDURE usp_ProcIDTest
AS
INSERT INTO Test ( TestID ) VALUES ( 1 )
GO
CREATE PROCEDURE usp_RootProcIDTest
AS
EXEC usp_ProcIDTest
GO
-- This XEvent session definition was kindly provided by XEvent 'New Session' wizard.
CREATE EVENT SESSION [catch_insertion_into_Test] ON SERVER
ADD EVENT sqlserver.error_reported(
ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_id,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack,sqlserver.username,sqlserver.context_info,sqlserver.plan_handle)
WHERE ([message] like N'catch_me%'))
ADD TARGET package0.ring_buffer(SET max_memory=(10240))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=ON)
GO
现在,如果启动XEvent会话(SSMS,对象资源管理器,管理,扩展事件,会话,catch_insertion_into_Test),执行usp_RootProcIDTest并查看XEvent会话的环形缓冲区,您将看到包含该节点的XML <action name="tsql_stack" package="sqlserver">
。有一系列帧节点。将handle
'属性的值放入系统函数'sys.dm_exec_sql_text'中,然后添加:
-- REPLACE MY HANDLES WITH YOURS
SELECT * FROM sys.dm_exec_sql_text(0x03000800D153096910272C01A6AA000000000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x030008000A78FD6912272C01A6AA000001000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x03000800439CF16A13272C01A6AA000001000000000000000000000000000000000000000000000000000000);
XEvent不仅可以让您做更多的事情!不要错过学习它们的机会!