如何使用内置函数解析数据库触发器的名称?


8

我有一个数据库触发器,用于防止我在用户数据库中创建某些过程。

它出现在中sys.triggers,带有object_id,但我无法使用该object_id功能来找到它。

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

坚果

同样,我可以在中找到它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;

坚果

是否有一个函数可以接受数据库级触发器的对象ID,并返回其名称?


不确定100%,但是您可以尝试sys.sql_expression_dependencies-> referenced_id加入sys.objects吗?
金沙

@Kin不会显示在sys>对象或所有对象中。很奇怪!
埃里克·达林

那很有趣.. parent_id按照bol怎么样object_id(object_name(parent_id))
金·沙

Answers:


9

数据库级和服务器级触发器本身并不限定为“对象”(这就是为什么您不能在模式下创建它们,以及为什么它们未显示在中sys.objects)的原因。

你可以看到,这些对象对他们有一定的限制,例如,在OBJECTPROPERTY()文档

此功能不能用于非架构范围的对象,例如数据定义语言(DDL)触发器和事件通知。

而在同样OBJECTPROPERTYEX()文档

OBJECTPROPERTYEX不能用于非架构范围的对象,例如数据定义语言(DDL)触发器和事件通知。

这些OBJECT_ID()文档更加明确:

不能使用OBJECT_ID来查询非模式范围的对象(例如DDL触发器)。对于在sys.objects目录视图中找不到的对象,请通过查询适当的目录视图来获取对象标识号。例如,要返回DDL触发器的对象标识号,请使用SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'。

这些OBJECT_NAME()文档不够明确,但是它们隐式提到了相同的限制(重点是我的):

返回模式范围的对象的数据库对象名称。


对于第一个查询,不确定为什么需要通过函数获取名称,因为其中的namesys.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等,则不必。


谢谢,亚伦 不,我只是发现他们没有正常解决感到奇怪。很高兴那奇怪的肉没有杀死你;)
埃里克·达林
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.