Como posso resolver o nome de um gatilho de banco de dados com funções internas?

8

Eu tenho um gatilho de banco de dados usado para me impedir de criar certos procedimentos nos bancos de dados do usuário.

Aparece em sys.triggers, com um object_id, mas não posso usar a object_idfunção para encontrá-lo.

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

NUTS

Da mesma forma, eu posso encontrá-lo sys.dm_exec_trigger_stats. Não consigo object_nameresolver, mas resolve 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

Existe uma função que aceite a identificação do objeto de um acionador no nível do banco de dados e retorne seu nome?

Erik Darling
fonte
Não tem 100% de certeza, mas você pode tentar sys.sql_expression_dependencies-> referenced_idingressar sys.objects?
Kin Shah
@ Kin não aparece em sys> objects ou em todos os objetos. Bem estranho!
Erik Darling
Isso é interessante .. que tal parent_idcomo por bol, por exemploobject_id(object_name(parent_id))
Kin Shah

Respostas:

9

Os gatilhos no nível do banco de dados e do servidor não têm o escopo definido como "objetos" em si (é por isso que você não pode criá-los em um esquema e por que eles não aparecem sys.objects).

Você pode ver que esses objetos têm certas restrições sobre eles, por exemplo, os OBJECTPROPERTY()documentos :

Esta função não pode ser usada para objetos sem escopo no esquema, como gatilhos DDL (linguagem de definição de dados) e notificações de eventos.

E da mesma forma nos OBJECTPROPERTYEX()docs :

OBJECTPROPERTYEX não pode ser usado para objetos sem escopo no esquema, como gatilhos DDL (linguagem de definição de dados) e notificações de eventos.

Os OBJECT_ID()documentos são um pouco mais explícitos:

Objetos sem escopo no esquema, como gatilhos DDL, não podem ser consultados usando OBJECT_ID. Para objetos que não são encontrados na exibição do catálogo sys.objects, obtenha os números de identificação do objeto consultando a exibição do catálogo apropriada. Por exemplo, para retornar o número de identificação do objeto de um gatilho DDL, use SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'.

Os OBJECT_NAME()documentos são menos explícitos, mas mencionam a mesma restrição implicitamente (ênfase minha):

Retorna o nome do objeto de banco de dados para objetos com escopo no esquema .


Para a primeira consulta, não sei por que você precisa obter o nome por meio da função, pois a namecoluna sys.triggersjá fornece essa resposta. Para a segunda consulta, você pode simplesmente se juntar a 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];

Você pode criar sua própria função, é claro, mas eu não conheço nenhuma função interna que faça essa correlação para você (e eu recomendo ficar longe das funções internas de metadados de qualquer maneira ).

Os gatilhos DDL são um tipo de animal especial. Portanto, se você estiver preocupado com a necessidade de participar de sys.procedures, sys.views etc., não faça isso.

Aaron Bertrand
fonte
Obrigado Aaron. Não, achei estranho que eles não resolvessem normalmente . Fico feliz que a carne estranha não matá-lo;)
Erik Darling