Есть ли какой-нибудь разумный способ перехватить зависимости объекта времени выполнения в SQL Server?
Например, возьмем такой сценарий динамического SQL:
DECLARE @table SYSNAME = 'SomeTable'
DECLARE @column SYSNAME = 'SomeColumn'
DECLARE @proc SYSNAME
DECLARE @command NVARCHAR(MAX) = 'SELECT TOP 1 @proc = '+@column+' FROM '+@table
EXEC sp_executesql @command, N'@proc SYSNAME OUTPUT', @proc OUTPUT
EXEC @proc
Зависимости времени выполнения будут SomeTable
, sp_executesql
, значение @proc
и любые объекты, на которые ссылаются во время выполнения с помощью процедуры @proc.
Методы, которые я рассмотрел до сих пор:
получение плана запросов xml из sys.dm_exec_query_plan из каждого пакета и передача его другому процессу через сервисный брокер для обработки. Плюсы: я думаю, что это может сработать. минусы: потенциально дорогие и навязчивые: каждый пакет и уровень выполнения должны быть модифицированы для захвата плана запроса.
расширенные события. плюсы: если это можно заставить работать, то отлично! минусы: я не думаю, что есть подходящий класс событий для "доступа к объектам", например, сканирование и / или поиск и / или выполнение и т. д. и т. д.
В идеале захват будет работать примерно так:
DECLARE @guid UNIQUEIDENTIFIER
EXEC usp_begin_object_capture @guid OUTPUT
DECLARE @table SYSNAME = 'SomeTable'
DECLARE @column SYSNAME = 'SomeColumn'
DECLARE @proc SYSNAME
DECLARE @command NVARCHAR(MAX) = 'SELECT TOP 1 @proc = '+@column+' FROM '+@table
EXEC sp_executesql @command, N'@proc SYSNAME OUTPUT', @proc OUTPUT
EXEC @proc
EXEC usp_stop_object_capture @guid
SELECT object_name FROM object_capture_table WHERE guid = @guid
------------------------------
object_name
------------------------------
SomeTable
sp_executesql
<proc_named_by_@proc>
<object1_referenced_by_@proc>
<object2_referenced_by_@proc>
<object3_referenced_by_@proc>
<objectn_referenced_by_@proc>
Контекст:
Я пытаюсь кэшировать / запоминать детерминированные наборы результатов длительных процедур. Базовые данные довольно статичны. Если бы я мог собрать фактические зависимости во время выполнения, я мог бы автоматически связать запись в кеше с набором объектов. Если какой-либо из этих объектов изменился, я бы знал, какие записи нужно сделать недействительными.
Это может быть плохая стратегия кеширования, я не знаю. Но техника зависимости все еще будет полезна в других контекстах.
Есть мысли? Большое спасибо.