我需要捕获哪些用户正在访问数据库中的视图。我最初的想法是使用扩展事件,但由于某种原因,当我测试时,没有捕获任何内容。这就是我到目前为止所拥有的。任何建议都将不胜感激。
-- 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_Trace\XE_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_Trace\XE_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发布于 2022-08-09 17:14:51
首先,让我们详细分析为什么每个XE会话都没有捕获对视图的访问,然后让我们看看是否可以做一个小的更改,以便其中之一做到这一点。
您标记为"test 1“的会话正在捕获sqlserver.module_start事件。尽管视图是模块(在编写这个答案之前,我不认为它们是模块,但sys.sql_modules的文档表明它们是),但是它们的开始和结束方式并不像存储过程或函数那样。所以这件事不是在开火。
您标记为"test 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
);https://stackoverflow.com/questions/73294885
复制相似问题