我有10个存储过程,每个过程都会插入一个tablex。

在Tablex的触发器主体中是否有可能导致TableX的修改(存储的Proc1或Sp2或....)?

谢谢你。

有帮助吗?

解决方案

是的,可以通过 使用@@ procid系统功能, ,以及更好的object_name(@@ procid)具有完整的名称。

定义:“返回当前Transact-SQL模块的对象标识符(ID)。transact-SQL模块可以是存储过程,用户定义的函数或触发器。处理数据访问提供商。”

你可以阅读 这里.

另一个选择是 检查当前蜘蛛的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的会话。并将保存在此处的上下文信息与每个过程相关联。例如,在过程1中,您将111写入上下文,在过程2中,您编写222 ..等等。

您可以阅读有关Context_info的更多信息 这个问题.

其他提示

我也想这样做。感谢你的回答。当我仍然在这里时,我会发布测试以节省其他时间:)

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

尽管SQL Server 2008可能不支持二手事件类型,但XEVENT提供了一种获取T-SQL堆栈的另一种方法。该解决方案由触发器,错误和XEVENT会话组成。我以吉姆·布朗(Jim Brown)的榜样来展示它的工作方式。

首先,我测试了SQL Server 2016 SP2CU2 DEV版本的解决方案。 SQL Server 2008支持一些exevent,但我没有任何实例,因此我无法测试它。

这个想法是在虚拟try-catch块中生成用户错误,然后在xevent会话中捕获错误 tsql_stack 行动。 SQLSERVER.error_reported 即使try-Catch块陷入困境,Xevent类型也可以捕获所有错误。到底, sys.dm_exec_sql_text 从查询手柄中提取T-SQL查询 tsql_stack 行动给出。

我开发的吉姆·布朗(Jim Brown)答案的一个例子如下所示。触发器通过文字“抓住我”提出了错误。 Xevent会话只有在“抓住我”之类的文本中捕获错误。

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会话(SSM,Object Explorer,管理,扩展事件,会话,Catch_insertion_into_test),执行USP_ROOTPROCIDTEST并查看XEVENT会话的戒指缓冲区,则应看到XML,该XML组成节点 <action name="tsql_stack" package="sqlserver">. 。有一系列帧节点。放置一个值 handle的属性到系统函数'sys.dm_exec_sql_text'和voilà:

-- 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);

An execution call stack example

XEvent让您做的不仅仅是这样!不要错过学习它们的机会!

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top