要捕获SQL Server中正在运行的视图的扩展事件



我需要捕获哪些用户正在访问数据库中的视图。我最初的想法是使用扩展事件,但由于某种原因,当我测试时,没有捕获到任何内容。这就是我到目前为止所拥有的。任何建议都将不胜感激。

-- Test 1
CREATE EVENT SESSION [Track_View] ON SERVER 
ADD EVENT sqlserver.module_start
(
SET collect_statement=1
ACTION
(
sqlserver.client_app_name,                
sqlserver.database_name,                   
sqlserver.session_server_principal_name,   
sqlserver.username,                        
sqlserver.sql_text,
sqlserver.tsql_stack
)
WHERE 
(
[object_type]='V ' 
AND [object_name]=N'MyView'
)
)
ADD TARGET package0.histogram(SET filtering_event_name=N'sqlserver.module_start',source=N'object_name',source_type=(0)),
ADD TARGET package0.event_file(SET filename=N'C:Event_TraceXE_Track_view.xel',max_rollover_files=(20))
WITH (MAX_MEMORY=1048576 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=ON,STARTUP_STATE=ON)
GO
-- Test 2
CREATE EVENT SESSION [Track_View] ON SERVER 
ADD EVENT sqlserver.sql_batch_starting(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.sql_text,sqlserver.username)

WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)) 

AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'myview') 

AND [sqlserver].[equal_i_sql_unicode_string]([sqlserver].[database_name],N'myDB') 

))

ADD TARGET package0.event_file(SET filename=N'C:Event_TraceXE_Track_view.xel',max_rollover_files=(20))
WITH (MAX_MEMORY=1048576 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=ON,STARTUP_STATE=ON)
GO

首先,让我们分析一下为什么每个XE会话都没有捕获对视图的访问权限,然后看看我们是否可以进行一个小的更改,使其中一个会话能够捕获对该视图的访问。


您标记为";测试1";正在捕获CCD_ 1事件。尽管视图是模块(在写这个答案之前,我不相信它们是模块,但sys.sql_modules的文档说它们是模块(,但它们的开始和结束方式与存储过程或函数不同。因此,该活动没有启动。


您标记为";测试2";有一个微妙的错误。让我们具体来看一下这个谓词:

[sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'myview')

因为它在搜索条件中没有任何通配符,所以这实际上表示[sqlserver].[sql_text] = N'myview'。将搜索条件更改为N'%myview%'就足够了。在我的测试†中,这就足够了。


我要注意的最后一件事是,XE可能不足以捕捉给定对象的所有用途。举个例子,一个基本对象是通过同义词间接引用的。我很幸运地使用了SQL审计功能(具有讽刺意味的是,它在后台使用XE(来跟踪对象的使用情况。它需要更多的设置,但就执行上下文而言,您可以获得大部分(如果不是全部的话(您想要的内容。对于您的用例,您希望根据视图审计部分或全部CRUD操作。


†这是我在测试中使用的XE会话。我使用了AdventureWorks的本地副本(这就是它引用vEmployee的原因(,并为我发出查询的会话添加了一个谓词(以避免发送XE会话的垃圾邮件(。但除此之外,方法是相同的。

CREATE EVENT SESSION [Track_View] ON SERVER 
ADD EVENT sqlserver.sql_batch_starting(
ACTION(
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.database_name,
sqlserver.nt_username,
sqlserver.sql_text,
sqlserver.username
)
WHERE (
[package0].[equal_boolean]([sqlserver].[is_system],(0)) 
AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%vEmployee%') 
AND [sqlserver].[session_id]=(70)
)
)
ADD TARGET package0.event_counter,
ADD TARGET package0.ring_buffer(SET max_events_limit=(10))
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=OFF
);

最新更新