Respostas:
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 :)
CREATE TABLE Test ( TestID INT )
GO
CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS
SELECT CAST(CONTEXT_INFO() AS NVARCHAR(128));
GO
CREATE PROCEDURE usp_ProcIDTest
AS
DECLARE @ProcedureName VARBINARY(MAX) = CAST(OBJECT_NAME(@@PROCID) AS VARBINARY(MAX))
SET CONTEXT_INFO @ProcedureName
INSERT INTO Test ( TestID ) VALUES ( 1 )
GO
EXEC usp_ProcIDTest
GO
DROP TABLE Test
GO
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 que tsql_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'.
CREATE TABLE Test ( TestID INT )
GO
CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS
BEGIN TRY
SET XACT_ABORT OFF; -- REALLY IMPORTANT!
/* make an catching a great deal more interesting */
DECLARE @TestID NVARCHAR(MAX) ;
SELECT TOP (1) @TestID = CAST(ins.TestID AS NVARCHAR(MAX)) FROM inserted AS ins ;
RAISERROR (N'catch_me TestID = "%s"' , 11 , 0 , @TestID) ;
END TRY BEGIN CATCH /* NOTHING TO DO */ END CATCH
GO
CREATE PROCEDURE usp_ProcIDTest
AS
INSERT INTO Test ( TestID ) VALUES ( 1 )
GO
CREATE PROCEDURE usp_RootProcIDTest
AS
EXEC usp_ProcIDTest
GO
-- This XEvent session definition was kindly provided by XEvent 'New Session' wizard.
CREATE EVENT SESSION [catch_insertion_into_Test] ON SERVER
ADD EVENT sqlserver.error_reported(
ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_id,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack,sqlserver.username,sqlserver.context_info,sqlserver.plan_handle)
WHERE ([message] like N'catch_me%'))
ADD TARGET package0.ring_buffer(SET max_memory=(10240))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=ON)
GO
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 do handle
atributo a na função do sistema 'sys.dm_exec_sql_text' e voilà:
-- REPLACE MY HANDLES WITH YOURS
SELECT * FROM sys.dm_exec_sql_text(0x03000800D153096910272C01A6AA000000000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x030008000A78FD6912272C01A6AA000001000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x03000800439CF16A13272C01A6AA000001000000000000000000000000000000000000000000000000000000);
O XEvent permite que você faça muito mais do que isso! Não perca oportunidades de aprendê-las!