답변:
예, @@ procid 시스템 기능 을 사용하여 실행중인 코드를 식별 하고 더 나은 OBJECT_NAME (@@ PROCID)을 사용하여 완전한 이름을 지정할 수 있습니다.
정의 : "현재 Transact-SQL 모듈의 개체 식별자 (ID)를 반환합니다. Transact-SQL 모듈은 저장 프로 시저, 사용자 정의 함수 또는 트리거 일 수 있습니다. @@ PROCID는 CLR 모듈 또는 프로세스 데이터 액세스 제공자. "
여기에서 읽을 수 있습니다 .
다른 옵션은 현재 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
SQL Server 2008은 사용 된 이벤트 유형을 지원하지 않을 수 있지만 XEvents는 T-SQL 스택을 알 수있는 또 다른 방법을 제공합니다. 솔루션은 트리거, 오류 및 XEvent 세션으로 구성됩니다. Jim Brown의 사례를 통해 작동 방식을 보여주었습니다.
우선, SQL Server 2016 SP2CU2 Dev Edition 용 솔루션을 테스트했습니다. SQL Server 2008은 일부 EXevent를 지원하지만 테스트 할 수없는 인스턴스가 없습니다.
아이디어는 더미 try-catch 블록에서 사용자 오류를 생성 한 다음 tsql_stack
조치를 통해 XEvent 세션 내에서 오류를 포착하는 것 입니다. SQLSERVER.error_reported
try-catch 블록이 오류를 포착하더라도 XEvent 유형은 모든 오류를 포착 할 수 있습니다. 결국, sys.dm_exec_sql_text
어떤 tsql_stack
조치가 제공 하는 쿼리 핸들에서 T-SQL 쿼리를 추출하십시오 .
내가 개발 한 Jim Brown의 답변의 예가 아래에 나와 있습니다. 트리거는 'catch me'텍스트와 함께 오류를 발생시킵니다. 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를 사용하면 이보다 더 많은 일을 할 수 있습니다! 그들을 배울 수있는 기회를 놓치지 마십시오!