Quando uma sys.algo pode te ajudar

Tempo de leitura estimado: 3 minutos

Bom galera, resolvi passar por aki, aproveitando que estou na hora do rango!

Aqui onde trabalho, estava acontecendo um erro em um dos servidores de teste quando alguem tentava logar no site que temos, tudo em ambiente de teste. A página era(é) uma página ASP.
O erro era esse:

Microsoft OLE DB Provider for ODBC Drivers error ‘80004005’

[Microsoft][ODBC SQL Server Driver][SQL Server]Logon failed for login ‘XXXXYYYYYYY’ due to trigger execution.[…]

XXXXYYYYYYY é o login que o IIS se usa pra se conectar no SQL Server. Se olharmos para o final vemos a frase “due to trigger execution”, em outras palavras ( literalmente ), “devido a execucao de uma trigger”. Na minha longa vida de SQL, eu vi que esse tipo de erro acontence quando temos triggers de Logon ( que sao na verdade DDL Trigers ) definidas no servidor.

Qual a solução ? Procurar pela danada e ver o porquê ela estava impedindo do IIS usar o SQL Server… e o problema começou aqui. Eu precisava de uma forma para encontrar as DDL triggers definidas no servidor.

A primeira tentativa foi em:

SELECT * FROM sys.triggers

Rodei no banco master ( que era o banco default do login ) e nada lá …
Por que ? Uma rápida olhada aqui no nesse artigo do BOL que tem a documentação dessa VIEW e vemos a descricao ali no começinho:

[…]”DML trigger names are schema-scoped and, therefore, are visible in sys.objects. DDL triggers names are scoped by the parent entity and are only visible in this view.”[…]

Isto é,em uma tradução vagabunda feita por mim mesmo:

“Triggers DML são definidas no escopo do esquema e portanto podem estar disponiveis em sys.objects.  Triggers DDL estão no escopo da entidade pai e são visíveis somente nesta view.”

Ou seja, podemos encontrar aqui tanto triggers DML quanto DDL. Mas as triggers DML também podem estar em sys.objects. Entidade pai é o tipo do objeto para o qual a trigger foi criada. Olhando na tabelinha um pouco abaixo desse trecho baixo vemos os seguintes valores para as colunas que informam qual a entidade pai: parent_class e parent_class_desc.

  • Parent_class pode ser 0 OU 1. Se for 0, significa que a trigger tem a Entidade DATABASE, e veremos exatamente esse nome na coluna parent_class_desc. Isto é, a trigger foi definida para eventos do Banco em que foi criada. Se for 1, significa que a trigger tem a Entidade OBJECT_OR_COLUMN, e veremos exatamente esse nome na coluna parent_class. Isto significa que a trigger foi criada para eventos em algum objeto .

Bom o importante aqui é que temos apenas dois valores possíveis pra parent_class e parent_class_desc… E nehum desses valores é igual a SERVER, ou algo do tipo, isto é, não irei ver triggers definidas para o servidor nessa view, já que Triggers de Logon são definidas para ALL SERVER e não somente DATABASE.

E lá vai eu tentar advinhar onde achar qual o nome da bendita trigger de logon… Quando googlando muito, eu encontro a bendita página. Olhando lá em baixo, no tópico “Getting Information About Logon Triggers”, eu encontro isso:

” You can view metadata about logon triggers by querying the sys.server_triggers catalog view. “

Vendo o nome sys.server_triggers, eu nao pensei em mais nada, nem cliquei no link, fui direito pro SSMS e executei a query:

SELECT * FROM sys.server_triggers

E lá estava ela, só tinha ela criada… quando vi o nome da trigger lá, lembrei que eu tinha criado a trigger pra alguns testes e que a mesma nao era importante. Dentro dela havia um insert em uma tabela, onde o login que estava se conectando pelo IIS nao tinha permissao de insert, gerando um erro e falhando o login. Dropei a danada, e como esperado, o IIS consegiu e o tudo funcionou sem problemas.

Bom, o que eu posso concluir com isso é:

  • Guarde as querys que te dao meta informações do servidor.
  • E guarde bem organizado para que você possa buscar isso facilmente depois.
  • E o mais importante: quando acabar a merda de algum teste lembra de desfazer as coisas que fez 🙂 !

Antes de terminar, creio eu que alguns podem se estar perguntando: Por que esse idiota nao usou o SSMS, foi lá em “Server Objects” e depois em “Triggers” ? ( Lá tem todas as triggers DDL definidas para o servidor )

  • Primeiro: Eu tinha me esquecido na hora e lembrei quando começei a escrever esse post.
  • Segundo: Mesmo se eu tivesse lembrando eu iria querer saber de todo jeito como eu faria pra consultar isso via T-SQL, pois se não tivesse o SSMS, e apenas um sqlcmd da vida, eu iria conseguir achar ela. 😉

Agora que eu tive que procurar, “sofrer” passando por alguns links e páginas, eu não esquecerei disso tão cedo.

Me desculpem erros de português, palavrões, etc … té a próxima !

[]s
Rodrigo Ribeiro Gomes

Compartilhe este post!

Comments ( 2 )

  1. / ReplyShizu
    Parabéns! adorei a iniciativa e melhor ainda foi esse post! continue assim trazendo sempre boas soluções para nossa equipe e compartilhando com a gente tb, pois hj o que foi sua duvida, pode ser a nossa amanhã. Vc vem desenvolvendo um bom trabalho aqui!!! Obrigada pelas ótimas soluções!!!

Leave a Reply to Rodrigo Ribeiro Gomes Cancel reply