Yanıtlar:
Evet, @@ procid sistem işlevini ve tam adı almak için daha iyi OBJECT_NAME (@@ PROCID) kullanarak çalışan kodu tanımlamak mümkündür .
Tanım: "Geçerli Transact-SQL modülünün nesne tanımlayıcısını (ID) döndürür. Transact-SQL modülü saklı yordam, kullanıcı tanımlı işlev veya tetikleyici olabilir. @@ PROCID CLR modüllerinde veya in- işlem veri erişim sağlayıcısı. "
Burada okuyabilirsiniz .
Başka bir seçenek , geçerli örgünün sql planını kontrol etmek ve bu bilgileri bir kayıt tablosuna kaydetmek olacaktır. Denetim verilerini kaydetmek için her prosedürde kullanılacak örnek bir sorgu şöyle olacaktır:
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
Belki orada çok fazla detay var ... ama bu fikri anladığınıza inanıyorum.
Üçüncü seçenek , geçerli SP oturumu için context_info bilgisini kullanmak olacaktır . Ve orada kaydedilen bağlam bilgisini her prosedürle bir yerde ilişkilendirin. Örneğin, yordam1'de bağlama 111 yazılır, yordam2'de 222 yazarsınız vb.
Context_info ile ilgili daha fazla bilgiyi bu SO sorusunda okuyabilirsiniz .
OBJECT_NAME(@@PROCID)
tetikleyici adı döner, çağıran proc değil.
Bunu ben de yapmak istedim. Cevap için teşekkürler. Hala burada olduğum için testimi başkalarına zaman kazandırmak için göndereceğim :)
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 kullanılan bir olay türünü desteklemese de, XEvents bir T-SQL yığını bilinmesi için başka bir yol sağlar. Çözüm bir tetikleyici, bir hata ve bir XEvent oturumundan oluşur. Jim Brown'un nasıl çalıştığını göstermek için örnek aldım.
Her şeyden önce, çözümü SQL Server 2016 SP2CU2 Dev Edition için test ettim. SQL Server 2008 bazı EXevent'i destekler, ancak test edemediğim için herhangi bir örneğim yok.
Fikir, sahte bir try-catch bloğunda bir kullanıcı hatası oluşturmak, ardından eylemle bir XEvent oturumu içinde hatayı yakalamaktır tsql_stack
. SQLSERVER.error_reported
XEvent türü, bir try-catch bloğu yakalasa bile tüm hataları yakalayabilir. Sonunda, sys.dm_exec_sql_text
hangi tsql_stack
eylem verir sorgu tanıtıcılarından T-SQL sorguları ayıklayın .
Geliştirdiğim Jim Brown cevabından bir örnek aşağıda gösterilmiştir. Bir tetikleyici 'beni yakala' metniyle hatayı yükseltir. XEvent oturumu yalnızca 'beni yakala' gibi metinlerle hataları yakalar.
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
Şimdi, XEvent oturumunu (SSMS, Nesne Gezgini, Yönetim, Genişletilmiş Olaylar, Oturumlar, catch_insertion_into_Test) başlatırsanız, usp_RootProcIDTest'i çalıştırır ve XEvent oturumunun halka arabelleğine bakarsanız, düğümü içeren XML'yi görmelisiniz <action name="tsql_stack" package="sqlserver">
. Bir dizi kare düğüm vardır. Bir handle
'özniteliğinin değerlerini ' sys.dm_exec_sql_text 'sistem işlevine koyun ve 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);
XEvent bundan daha fazlasını yapmanıza izin verir! Onları öğrenme fırsatlarını kaçırmayın!