it-swarm.com.de

Verwenden des erweiterten Ereignisses zum Verfolgen von Aktualisierungen einer Tabelle

Ich habe eine Tabelle, die ständig aktualisiert wird, und niemand kann herausfinden, woher die Aktualisierungen kommen. Ich vermute, dass sie von Entity Framework stammen, aber ich möchte das UPDATE und die zugehörigen Informationen über ein erweitertes Ereignis erfassen, um diese Theorie zu beweisen.

Ich bin in SQL 2014 Enterprise und versuche, diese Informationen mithilfe der Ereignisse exec_prepared_sql und sql_statement_starting zu erfassen. Folgendes habe ich bisher:

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

Dies scheint gut zu funktionieren, ich habe es getestet und konnte sowohl eine reguläre UPDATE-Anweisung als auch eine mit sp_executesql aufgerufene Anweisung erfassen. Mir fehlt jedoch noch etwas. Die Daten in der Tabelle werden noch geändert, und dieses erweiterte Ereignis erfasst nicht das UPDATE, das dies tut.

Meine Fragen sind also:

1) Gibt es noch etwas, das ich in meinem erweiterten Ereignis beobachten muss, um UPDATES zu erfassen, die möglicherweise von Entity Framework stammen?

2) Gibt es etwas anderes, das ich anstelle von Extended Events verwenden sollte?

Vielen Dank!

7
Eric Cobb

Wenn Sie SQL Server Enterprise Edition verwenden (oder eine neuere Edition als 2016 SP1 ausführen), würde ich empfehlen, die SQLAudit-Funktionalität zu verwenden. Auf diese Weise erhalten Sie einige detaillierte Informationen darüber, wer Ihre Tabellen berührt und welche Befehle ausgeführt werden.

Für so etwas möchten Sie ein Datenbank-Audit-Spezifikation zusammen mit einem Server-Audit (verwendet, um zu definieren, wohin Ihr Audit schreiben soll) verwenden und es dann auf etwas reduzieren die Tabelle, die Sie überwachen möchten. Wenn Sie dann Änderungen an der öffentlichen Rolle vornehmen, erfassen Sie alle Änderungen, die auftreten.

Dieses Skript sollte Sie dorthin bringen (testen Sie in Ihrer Entwicklungsumgebung und ersetzen Sie die relevanten Teile für die Tabelle (n), die Sie überwachen möchten).

USE [master]

GO

CREATE SERVER AUDIT [Audit-TblChanges]
TO FILE 
(   FILEPATH = N'C:\SQLAudit'
    ,MAXSIZE = 0 MB
    ,MAX_ROLLOVER_FILES = 2147483647
    ,RESERVE_DISK_SPACE = OFF
)
WITH
(   QUEUE_DELAY = 1000
    ,ON_FAILURE = CONTINUE
)

GO

USE [YourDatabase]
GO

CREATE DATABASE AUDIT SPECIFICATION [DatabaseAuditSpecification-MyTable]
FOR SERVER AUDIT [Audit-TblChanges]
ADD (UPDATE ON OBJECT::[YourTable] BY [public]),
ADD (INSERT ON OBJECT::[YourTable] BY [public])

GO


USE [master]
GO
ALTER SERVER AUDIT [Audit-TblChanges] WITH (STATE = ON);

USE [YourDatabase]
GO
ALTER DATABASE AUDIT SPECIFICATION [DatabaseAuditSpecification-MyTable] WITH (STATE = ON);
GO

Sie können die Daten schnell über die GUI zurücklesen oder sys.fn_get_audit_file verwenden, um die Daten direkt von SQL Server abzufragen.

9
Nic