Как мне разрешить имя триггера базы данных с помощью встроенных функций?

8

У меня есть триггер базы данных, который я использую, чтобы предотвратить создание определенных процедур в пользовательских базах данных.

Он появляется в sys.triggers, с object_id, но я не могу использовать object_idфункцию, чтобы найти его.

SELECT OBJECT_ID(t.name, t.type) AS object_id, *
FROM   sys.triggers AS t;

NUTS

Точно так же я могу найти это в sys.dm_exec_trigger_stats. Я не могу object_nameрешить, но object_definitionэто так.

SELECT OBJECT_NAME(dets.object_id, dets.database_id) AS object_name,
       OBJECT_DEFINITION(dets.object_id) AS object_definition,
       *
FROM   sys.dm_exec_trigger_stats AS dets;

NUTS

Существует ли функция, которая будет принимать идентификатор объекта триггера уровня базы данных и возвращать его имя?

Эрик Дарлинг
источник
Не уверен на 100%, но вы можете попробовать sys.sql_expression_dependencies-> referenced_idприсоединиться sys.objects?
Кин Шах
@Kin это не отображается в sys> объектах или всех объектах. Довольно странно!
Эрик Дарлинг
Вот интересно .. как насчет parent_idсогласно бол , напримерobject_id(object_name(parent_id))
Kin Шах

Ответы:

9

Триггеры на уровне базы данных и сервера сами по себе не ограничены как «объекты» (вот почему вы не можете создать их в схеме и почему они не отображаются в ней sys.objects).

Вы можете видеть , что эти объекты имеют определенные ограничения на них, например , в той OBJECTPROPERTY()документации :

Эта функция не может использоваться для объектов, которые не относятся к области действия схемы, таких как триггеры языка определения данных (DDL) и уведомления о событиях.

И точно так же в той OBJECTPROPERTYEX()документации :

OBJECTPROPERTYEX нельзя использовать для объектов, которые не относятся к области действия схемы, таких как триггеры языка определения данных (DDL) и уведомления о событиях.

В OBJECT_ID()Документах немного более четко:

Объекты, не относящиеся к области действия схемы, такие как триггеры DDL, не могут быть запрошены с помощью OBJECT_ID. Для объектов, которые не найдены в представлении каталога sys.objects, получите идентификационные номера объектов, запросив соответствующее представление каталога. Например, чтобы вернуть идентификационный номер объекта триггера DDL, используйте SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'.

Эти OBJECT_NAME()документы являются менее явными, но они упоминают же ограничение неявно (курсив мой):

Возвращает имя объекта базы данных для объектов в области схемы .


Для первого запроса не уверен, почему вам нужно получить имя через функцию, так как nameстолбец sys.triggersуже дает вам этот ответ. Для второго запроса вы можете просто присоединиться к sys.triggers:

SELECT tr.*, ts.*
FROM sys.dm_exec_trigger_stats AS ts
LEFT OUTER JOIN sys.triggers AS tr
ON ts.[object_id] = tr.[object_id];

Конечно, вы можете создать свою собственную функцию, но я не знаю каких-либо встроенных функций, которые бы обеспечивали эту взаимосвязь для вас (и я рекомендую вообще избегать встроенных функций метаданных ).

DDL триггеры являются своего рода специальным животным. Так что если вы беспокоитесь о необходимости присоединиться к sys.procedures, sys.views и т. Д., Не делайте этого.

Аарон Бертран
источник
Спасибо, Аарон. Нет, мне показалось странным, что они не разрешаются нормально . Рад, что странное мясо не убило тебя;)
Эрик Дарлинг