У меня есть 10 хранимых процедур, и каждая из них делает вставки в одну таблицуX.
Возможно ли в теле триггера tableX получить, какой объект вызывает модификацию tableX (хранится в proc1 или sp2 или ....)?
Спасибо.
источник
У меня есть 10 хранимых процедур, и каждая из них делает вставки в одну таблицуX.
Возможно ли в теле триггера tableX получить, какой объект вызывает модификацию tableX (хранится в proc1 или sp2 или ....)?
Спасибо.
Да, можно определить работающий код, используя системную функцию @@ procid , и лучше присвоить 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
Может быть, там слишком много деталей .. но я верю, что вы поняли идею.
Третий вариант - использовать информацию context_info для текущего сеанса SP. И связать где-нибудь контекстную информацию, сохраненную там с каждой процедурой. Например, в процедуре1 вы пишете 111 в контекст, в процедуре2 вы пишете 222 .. и так далее.
Много больше информации о context_info вы можете прочитать в этом вопросе SO .
OBJECT_NAME(@@PROCID)
возвращается имя триггера, а не вызывающий процесс.Я тоже хотел это сделать. Спасибо за ответ. Поскольку я все еще здесь, я опубликую свой тест, чтобы сэкономить время других :)
источник
XEvents предоставляют другой способ получения стека T-SQL, хотя SQL Server 2008 может не поддерживать используемый тип событий. Решение состоит из триггера, ошибки и сеанса XEvent. Я взял пример Джима Брауна, чтобы показать, как он работает.
Прежде всего, я протестировал решение для SQL Server 2016 SP2CU2 Dev Edition. SQL Server 2008 поддерживает некоторые EXevent, но у меня нет ни одного экземпляра, чтобы я не смог его протестировать.
Идея состоит в том, чтобы сгенерировать пользовательскую ошибку в фиктивном блоке try-catch, а затем перехватить ошибку в сеансе XEvent с
tsql_stack
действием.SQLSERVER.error_reported
Тип XEvent может перехватывать все ошибки, даже если блок try-catch их перехватывает. В концеsys.dm_exec_sql_text
извлеките запросы T-SQL из дескрипторов запросов, которыеtsql_stack
дает действие.Пример из ответа Джима Брауна, который я разработал, показан ниже. Триггер вызывает ошибку с текстом «поймай меня». Сессия XEvent ловит ошибки только с текстом типа «поймай меня».
Теперь, если вы запустите сеанс XEvent (SSMS, Обозреватель объектов, Управление, Расширенные события, Сеансы, catch_insertion_into_Test), выполните usp_RootProcIDTest и посмотрите кольцевой буфер сеанса XEvent, вы должны увидеть XML, который состоит из узла
<action name="tsql_stack" package="sqlserver">
. Существует последовательность узлов кадра. Поместите значенияhandle
атрибута в системную функцию 'sys.dm_exec_sql_text' и вуаля:XEvent позволит вам сделать гораздо больше, чем это! Не упустите возможности узнать их!
источник