You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何查询访问SQL Server数据库的用户及指定时段访问特定库的用户

Hey there, let's break down these two SQL Server user access questions with practical, actionable solutions:

1. 找出所有访问过SQL Server数据库的用户

The approach here depends on whether you need current active users or historical access records:

Current/Recently Active Users

For users who are currently connected or have accessed the database recently (before their session was cleaned up), use dynamic management views (DMVs):

SELECT DISTINCT 
    s.session_id,
    s.login_name,
    db.name AS database_name,
    s.host_name,
    s.program_name,
    s.last_request_start_time
FROM sys.dm_exec_sessions s
JOIN sys.databases db ON s.database_id = db.database_id
WHERE s.is_user_process = 1; -- 排除系统进程

Note: DISTINCT removes duplicate entries from the same user session, and is_user_process = 1 filters out internal SQL Server system sessions.

Historical Access Records

To pull past access data, you'll need to have had logging enabled beforehand. Here are two common methods:

  • SQL Server Audit (if configured)
    If you set up server or database-level auditing, use the audit file reader function:

    SELECT DISTINCT 
        event_time,
        session_server_principal_name AS login_name,
        database_name
    FROM sys.fn_get_audit_file('C:\YourAuditLogPath\*.sqlaudit', DEFAULT, DEFAULT)
    WHERE action_id IN ('LGI', 'DBC') -- 锁定登录和数据库连接事件
    ORDER BY event_time DESC;
    

    Replace the file path with your actual audit log directory.

  • SQL Server Error Log
    Use this to check recent successful login events (logs rotate regularly, so older records may be gone):

    EXEC xp_readerrorlog 0, 1, 'Login succeeded'; -- 0 = 当前日志, 1 = 上一份日志
    
2. 查询指定时间段内访问特定SQL Server数据库的所有用户

Again, split this into real-time/recent and historical scenarios:

Real-Time/Recent Access

Use DMVs to filter for your target database and time range:

SELECT DISTINCT 
    s.login_name,
    s.host_name,
    s.program_name,
    s.last_request_start_time,
    s.last_request_end_time
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_requests r ON s.session_id = r.session_id
WHERE s.database_id = DB_ID('YourTargetDatabase') -- 替换为你的数据库名
  AND s.is_user_process = 1
  AND s.last_request_start_time BETWEEN '2024-01-01 00:00:00' AND '2024-01-02 23:59:59'; -- 调整时间范围

last_request_start_time记录了用户最后一次查询/操作的开始时间,能覆盖在时间窗口内访问过数据库的用户。

Historical Access (Pre-Configured Logging)

  • Audit File Method
    给审计查询添加数据库和时间筛选条件:

    SELECT DISTINCT 
        event_time,
        session_server_principal_name AS login_name,
        database_name
    FROM sys.fn_get_audit_file('C:\YourAuditLogPath\*.sqlaudit', DEFAULT, DEFAULT)
    WHERE database_name = 'YourTargetDatabase'
      AND action_id IN ('LGI', 'DBC')
      AND event_time BETWEEN '2024-01-01 00:00:00' AND '2024-01-02 23:59:59'
    ORDER BY event_time DESC;
    
  • Extended Events (if configured)
    如果你创建了跟踪数据库访问的扩展事件会话,可以查询对应的事件文件:

    SELECT 
        event_data.value('(event/@timestamp)[1]', 'datetime') AS event_time,
        event_data.value('(event/data[@name="login_name"]/value)[1]', 'nvarchar(100)') AS login_name,
        event_data.value('(event/data[@name="database_name"]/value)[1]', 'nvarchar(100)') AS database_name
    FROM (
        SELECT CAST(event_data AS XML) AS event_data
        FROM sys.fn_xe_file_target_read_file('C:\YourXEventsPath\SessionName_*.xel', DEFAULT, DEFAULT)
    ) AS x
    WHERE event_data.value('(event/data[@name="database_name"]/value)[1]', 'nvarchar(100)') = 'YourTargetDatabase'
      AND event_data.value('(event/@timestamp)[1]', 'datetime') BETWEEN '2024-01-01 00:00:00' AND '2024-01-02 23:59:59'
    ORDER BY event_time DESC;
    

    替换文件路径和会话名为你的实际配置即可。

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

火山引擎 最新活动