Відповіді:
Так, можна визначити запущений код, використовуючи системну функцію @@ і краще OBJECT_NAME (@@ PROCID), щоб мати повне ім'я.
Визначення: "Повертає ідентифікатор об'єкта (ID) поточного модуля Transact-SQL. Модуль Transact-SQL може бути збереженою процедурою, визначеною користувачем функцією або тригером. @@ PROCID не можна вказати в модулях CLR або в обробляти провайдер доступу до даних. "
Про це можна прочитати тут .
Іншим варіантом було б перевірити sql-план поточного spid та зберегти цю інформацію в таблиці реєстрації. Зразок запиту, який використовується в кожній процедурі для збереження даних аудиту, буде:
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
Можливо, там є занадто багато деталей ... але я вважаю, що ви зрозуміли цю ідею.
Третім варіантом буде використання інформації контексту_інфо для поточного сеансу СП. І пов’язати десь інформацію про контекст, збережену там, з кожною процедурою. Наприклад, у процедурі1 ви пишете 111 у контекст, у процедурі2 ви пишете 222 .. і так далі.
Набагато більше інформації про контекстну інформацію ви можете прочитати в цьому питанні .
OBJECT_NAME(@@PROCID)
повертає ім'я тригера, а не прок.
Я теж хотів це зробити. Дякую за відповідь. Оскільки я все ще тут, я опублікую свій тест, щоб заощадити час :)
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. Я взяв приклад Джима Брауна, щоб показати, як це працює.
Перш за все, я протестував рішення для SQL Server 2016 SP2CU2 Dev Edition. SQL Server 2008 підтримує деякий EXevent, але у мене немає жодного примірника, щоб я не міг його перевірити.
Ідея полягає в тому, щоб генерувати помилку користувача у фіксованому блоці спроб лову, а потім вловлювати помилку в сеансі XEvent з tsql_stack
дією. SQLSERVER.error_reported
Тип XEvent може вловлювати всі помилки, навіть якщо блок пробного захоплення захоплює їх. Зрештою, sys.dm_exec_sql_text
витягніть T-SQL запити з оброблюваних запитів, які tsql_stack
дає дія.
Приклад з відповіді Джима Брауна, який я розробив, наведено нижче. Тригер викликає помилку з текстом "лови мене". Сеанс 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 (SSMS, провідник об’єктів, управління, розширені події, сеанси, catch_insertion_into_Test), виконайте usp_RootProcIDTest і подивіться буфер дзвінка сеансу XEvent, ви повинні побачити XML, що складається з вузла <action name="tsql_stack" package="sqlserver">
. Існує послідовність вузлів кадру. Помістіть значення handle
атрибута 's у функцію системи' 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);
XEvent дозволить вам зробити набагато більше, ніж це! Не пропустіть можливості навчитися їх!