Eu tenho 10 procedimentos armazenados e cada um deles faz INSERTs em uma tabelaX.
É possível, em um corpo de gatilho da tabelaX, obter qual objeto causa a modificação da tabelaX (proc1 armazenado ou sp2 ou ....)?
Obrigado.
fonte
Eu tenho 10 procedimentos armazenados e cada um deles faz INSERTs em uma tabelaX.
É possível, em um corpo de gatilho da tabelaX, obter qual objeto causa a modificação da tabelaX (proc1 armazenado ou sp2 ou ....)?
Obrigado.
Sim, é possível identificar o código em execução usando a função do sistema @@ procid e melhor OBJECT_NAME (@@ PROCID) para ter o nome completo.
Definição: "Retorna o identificador do objeto (ID) do módulo Transact-SQL atual. Um módulo Transact-SQL pode ser um procedimento armazenado, função definida pelo usuário ou gatilho. @@ PROCID não pode ser especificado nos módulos CLR ou no módulo fornecedor de acesso a dados do processo ".
Você pode ler sobre isso aqui .
Outra opção seria verificar o plano sql do spid atual e salvar essas informações em uma tabela de log. Uma consulta de amostra a ser usada em cada procedimento para salvar dados de auditoria seria:
select sp.hostname, sp.program_name, sp.loginame,
st.text as query_text
from sysprocesses sp
cross apply sys.dm_exec_sql_text(sp.sql_handle) as st
where sp.spid = @@spid
Talvez haja muitos detalhes lá ... mas acredito que você entendeu a idéia.
Uma terceira opção seria usar as informações context_info na sessão do SP atual. E associe em algum lugar a informação de contexto salva lá com cada procedimento. Por exemplo, no procedimento1, você escreve 111 no contexto, no procedimento2, escreve 222 .. e assim por diante.
Muito mais informações sobre context_info você pode ler nesta pergunta do SO .
OBJECT_NAME(@@PROCID)
retorna o nome do gatilho, não o processo de chamada.Eu também queria fazer isso. Obrigado pela resposta. Como ainda estou aqui, publicarei meu teste para economizar tempo :)
fonte
O XEvents fornece outra maneira de tornar conhecida uma pilha T-SQL, embora o SQL Server 2008 possa não suportar um tipo de evento usado. A solução consiste em um gatilho, um erro e uma sessão XEvent. Peguei o exemplo de Jim Brown para mostrar como funciona.
Antes de tudo, testei a solução para o SQL Server 2016 SP2CU2 Dev Edition. O SQL Server 2008 suporta alguns EXevent, mas não tenho nenhuma instância para não poder testá-lo.
A idéia é gerar um erro do usuário em um bloco de tentativa e captura simulado e capturar o erro dentro de uma sessão do XEvent com
tsql_stack
ação.SQLSERVER.error_reported
O tipo XEvent pode capturar todos os erros, embora um bloco try-catch os prenda. No final,sys.dm_exec_sql_text
extraia as consultas T-SQL das alças de consulta quetsql_stack
ação fornece.Um exemplo da resposta de Jim Brown, que desenvolvi, é mostrado abaixo. Um gatilho gera o erro com o texto 'catch me'. A sessão do XEvent captura erros apenas com o texto como 'catch me'.
Agora, se você iniciar a sessão do XEvent (SSMS, Pesquisador de Objetos, Gerenciamento, Eventos Estendidos, Sessões, catch_insertion_into_Test), execute usp_RootProcIDTest e procure o buffer de anel da sessão do XEvent, deverá ver o XML que consiste no nó
<action name="tsql_stack" package="sqlserver">
. Há uma sequência de nós de quadros. Coloque os valores dohandle
atributo a na função do sistema 'sys.dm_exec_sql_text' e voilà:O XEvent permite que você faça muito mais do que isso! Não perca oportunidades de aprendê-las!
fonte