Jawaban:
Ya, adalah mungkin untuk mengidentifikasi kode yang sedang berjalan, dengan menggunakan fungsi sistem @@ procid , dan OBJECT_NAME (@@ PROCID) yang lebih baik untuk memiliki nama lengkap.
Definisi: "Mengembalikan objek pengidentifikasi (ID) dari modul Transact-SQL saat ini. Modul Transact-SQL dapat berupa prosedur tersimpan, fungsi yang ditentukan pengguna, atau pemicu. @@ PROCID tidak dapat ditentukan dalam modul CLR atau modul memproses penyedia akses data. "
Anda dapat membacanya di sini .
Opsi lain adalah memeriksa paket sql dari spid saat ini dan menyimpan info itu di tabel logging. Kueri sampel yang akan digunakan dalam setiap prosedur untuk menyimpan data audit adalah:
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
Mungkin ada terlalu banyak detail di sana..tapi saya percaya Anda mendapatkan idenya.
Opsi ketiga adalah menggunakan informasi context_info untuk sesi SP saat ini. Dan kaitkan suatu tempat informasi konteks disimpan di sana dengan setiap prosedur. Misalnya dalam procedure1 Anda menulis 111 ke konteks, di procedure2 Anda menulis 222 .. dan seterusnya
Lebih banyak info mengenai context_info yang dapat Anda baca dalam pertanyaan SO ini .
OBJECT_NAME(@@PROCID)
mengembalikan nama pemicu, bukan proc panggilan.
Saya ingin melakukan ini juga. Terima kasih atas jawabannya. Karena saya masih di sini, saya akan memposting tes saya untuk menghemat waktu orang lain :)
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 menyediakan cara lain untuk mengenal tumpukan T-SQL meskipun SQL Server 2008 mungkin tidak mendukung jenis peristiwa yang digunakan. Solusi terdiri dari pemicu, kesalahan, dan sesi XEvent. Saya mengambil contoh Jim Brown untuk menunjukkan cara kerjanya.
Pertama-tama, saya menguji solusi untuk SQL Server 2016 SP2CU2 Dev Edition. SQL Server 2008 mendukung beberapa EXevent, tapi saya tidak punya contoh sehingga saya tidak bisa mengujinya.
Idenya adalah untuk menghasilkan kesalahan pengguna di blok try-catch dummy, kemudian menangkap kesalahan di dalam sesi XEvent dengan tsql_stack
tindakan. SQLSERVER.error_reported
Tipe XEvent dapat menangkap semua kesalahan meskipun blok try-catch menjebaknya. Pada akhirnya, sys.dm_exec_sql_text
ekstrak kueri T-SQL dari kueri menangani tsql_stack
tindakan yang diberikan.
Contoh dari jawaban Jim Brown, yang saya kembangkan, ditunjukkan di bawah ini. Pemicu memunculkan kesalahan dengan teks 'tangkap aku'. Sesi XEvent menangkap kesalahan hanya dengan teks seperti 'tangkap saya'.
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
Sekarang, jika Anda meluncurkan sesi XEvent (SSMS, Object Explorer, Manajemen, Acara yang Diperpanjang, Sesi, catch_insertion_into_Test), jalankan usp_RootProcIDTest dan lihat buffer cincin sesi XEvent, Anda akan melihat XML yang terdiri dari node <action name="tsql_stack" package="sqlserver">
. Ada urutan frame node. Masukkan nilai handle
atribut 's ke fungsi sistem' sys.dm_exec_sql_text ', dan 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 membiarkan Anda melakukan lebih dari ini! Jangan lewatkan kesempatan untuk mempelajarinya!