You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQL Server扩展事件捕获访问视图的用户

扩展事件捕获视图访问的优化方案

原测试代码的问题分析

Test 1 问题

  • object_type过滤值错误:[object_type]='V '包含多余空格,SQL Server中视图的object_type值是'V'(无空格),这是导致无数据捕获的核心原因。
  • 缺少数据库过滤:未限定目标数据库,可能捕获其他库同名视图的访问,也会增加不必要的事件量。
  • 未排除系统操作:没有过滤sqlserver.is_system = 0,会捕获SQL Server内部的系统访问操作。

Test 2 问题

  • sql_text匹配不可靠:用like_i_sql_unicode_string匹配sql_text中的视图名称,无法覆盖所有场景(比如视图被别名引用、嵌套在子查询/存储过程中,或者语句中包含与视图名相同的字符串),会出现漏捕或误捕。
  • 仅捕获批量查询开始:sql_batch_starting只能捕获即席查询的开始事件,无法捕获通过存储过程、函数等模块调用视图的场景。

优化后的扩展事件会话代码

方案1:精确捕获所有视图访问(推荐)

使用sqlserver.object_accessed事件,能够精确捕获任何方式(直接查询、模块调用、嵌套访问)对视图的访问,过滤条件更精准:

CREATE EVENT SESSION [Track_View_Access] ON SERVER 
ADD EVENT sqlserver.object_accessed(
    ACTION(
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.database_name,
        sqlserver.session_server_principal_name,
        sqlserver.username,
        sqlserver.sql_text,
        sqlserver.tsql_stack
    )
    WHERE 
    (
        sqlserver.is_system = 0 -- 排除系统操作
        AND object_type = 'V' -- 视图类型,无空格
        AND object_name = N'MyView' -- 目标视图名
        AND 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

方案2:修正Test1的module_start事件

如果坚持使用module_start,修正过滤条件并补充必要限制:

CREATE EVENT SESSION [Track_View_Module] 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 
    (
        sqlserver.is_system = 0 -- 排除系统操作
        AND object_type = 'V' -- 修正为无空格的'V'
        AND object_name = N'MyView'
        AND database_name = N'myDB' -- 限定数据库
    )
)
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

关键注意事项

  1. 启动事件会话:创建完成后需执行ALTER EVENT SESSION [Track_View_Access] ON SERVER STATE = START;启动会话,否则不会捕获数据。
  2. 权限验证:确保创建会话的账号拥有ALTER ANY EVENT SESSION权限,查看事件文件需要对应文件系统权限。
  3. 测试验证:使用不同方式访问视图(直接查询、存储过程调用、应用程序访问),然后通过以下语句查看捕获的事件数据:
SELECT 
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    event_data.value('(event/@timestamp)[1]', 'datetime2') AS event_time,
    event_data.value('(event/action[@name="database_name"]/value)[1]', 'varchar(100)') AS database_name,
    event_data.value('(event/action[@name="session_server_principal_name"]/value)[1]', 'varchar(100)') AS login_name,
    event_data.value('(event/action[@name="username"]/value)[1]', 'varchar(100)') AS database_user,
    event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'varchar(100)') AS client_app,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS sql_text
FROM 
    (SELECT CAST(event_data AS XML) AS event_data FROM sys.fn_xe_file_target_read_file('C:\Event_Trace\XE_Track_view*.xel', NULL, NULL, NULL)) AS x
ORDER BY 
    event_time DESC;

内容的提问来源于stack exchange,提问作者dan Kalio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:06:24