Eu tenho uma tabela que continua sendo atualizada e ninguém consegue descobrir de onde as atualizações estão vindo. Eu suspeito que eles estão vindo do Entity Framework, mas eu quero capturar o UPDATE e as informações associadas por meio de um Extended Event para provar essa teoria.
Estou no SQL 2014 Enterprise e estou tentando capturar essas informações usando os eventos exec_prepared_sql e sql_statement_starting. Aqui está o que eu tenho até agora:
CREATE EVENT SESSION [Query Trace] ON SERVER
ADD EVENT sqlserver.exec_prepared_sql(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123))),
ADD EVENT sqlserver.sql_statement_starting(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123)))
ADD TARGET package0.event_file(SET filename=N'E:\ExtendedEvent\Query-Trace.xel')
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=ON,STARTUP_STATE=OFF)
GO
Isso parece funcionar bem, eu testei e consegui capturar uma instrução UPDATE regular e uma chamada com sp_executesql. No entanto, ainda estou faltando alguma coisa. Os dados na tabela ainda estão sendo modificados e este Extended Event não está capturando a UPDATE que faz isso.
Então, minhas perguntas são:
1) Existe algo mais que eu preciso estar assistindo no meu Evento Estendido para capturar ATUALIZAÇÕES possivelmente provenientes do Entity Framework?
2) Existe algo mais que eu deveria usar em vez de Eventos Estendidos para isso?
Obrigado!
Ao usar o SQL Server Enterprise Edition (ou executar qualquer edição mais recente que 2016 SP1), recomendo usar a funcionalidade SQLAudit. Isso lhe dará ótimas informações granulares sobre quem está tocando suas tabelas e os comandos que estão sendo executados.
Para algo assim, você deve usar uma especificação de auditoria de banco de dados junto com uma auditoria de servidor (usada para definir onde sua auditoria gravará) e, em seguida, definir o escopo para a tabela que deseja monitorar. Ao definir o escopo das alterações na função pública, você capturará todas e quaisquer alterações que ocorrerem.
Este script deve levá-lo até lá (teste em seu ambiente de desenvolvimento e substitua as partes relevantes da(s) tabela(s) que você deseja monitorar).
Você pode ler rapidamente os dados usando a GUI ou usar sys.fn_get_audit_file para consultar os dados diretamente do SQL Server.
Para quem não tem a funcionalidade SQLAudit desta resposta disponível e está fazendo esse tipo de coisa puramente com eventos estendidos: há mais eventos que você deve assistir do que apenas os dois listados na pergunta.
Eu uso esta lista de eventos como meu ponto de partida:
Pode haver alguma sobreposição entre eles, mas não penso demais; Prefiro ver vários eventos relevantes do que nenhum.
Em particular, as atualizações de tabela que estou solucionando agora são todas provenientes
sp_statement_starting
erpc_starting
eventos, nenhum dos quais o redator de perguntas estava pegando.