在sql server中,获取历史sql执行者的需求确实是一个挑战,因为sql server的动态管理视图(dmv)主要用于实时监控和获取当前活动的信息,而不是历史数据。让我们来探讨一下这个问题,并提供一些可能的解决方案。
首先,让我们回顾一下你提供的信息:
Oracle的实现:在Oracle中,可以通过
v$sql视图的parsing_schema_name字段获取执行SQL的用户信息。-
SQL Server的现状:
- 你找到了
sys.dm_exec_cached_plans和sys.dm_exec_sql_text来获取当前缓存的SQL语句,但这些视图不包含用户信息。 - 你也尝试了
sys.dm_exec_sessions来获取登录用户信息,但无法直接关联到具体的SQL语句。 - 最后,你找到了一条查询,可以获取当前正在执行的SQL和会话信息,但这仅限于当前执行的SQL,不包括历史数据。
- 你找到了
大师的建议:SQL Server不能通过DMV视图直接查询历史SQL,只能通过不断采集当前会话的SQL并保存下来。
基于这些信息,我们可以考虑以下解决方案:
1. 使用SQL Server Profiler或Extended Events
SQL Server Profiler和Extended Events可以用来捕获SQL语句的执行信息,包括用户信息。这些工具可以设置为持续运行,并将数据保存到文件或表中。
示例使用Extended Events:
CREATE EVENT SESSION [CaptureSQLExecutions] ON SERVER
ADD EVENT sqlserver.sql_batch_completed(
ACTION(sqlserver.client_hostname, sqlserver.username)
WHERE ([sqlserver].[database_name]=N'XXX')
)
ADD TARGET package0.event_file(SET filename=N'C:\SQLServer\CaptureSQLExecutions.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=OFF,STARTUP_STATE=OFF)
GO
ALTER EVENT SESSION [CaptureSQLExecutions] ON SERVER STATE = START
GO
你可以使用以下查询来读取捕获的数据:
SELECT
CAST(event_data AS XML).value('(/event/action[@name="username"]/text())[1]', 'nvarchar(128)') AS [Username],
CAST(event_data AS XML).value('(/event/data[@name="batch_text"]/value)[1]', 'nvarchar(max)') AS [SQLText]
FROM sys.fn_xe_file_target_read_file('C:\SQLServer\CaptureSQLExecutions*.xel', NULL, NULL, NULL)2. 使用SQL Server Audit
SQL Server Audit可以用来记录数据库活动,包括SQL语句和执行用户。
示例设置Audit:
USE [master] GOCREATE SERVER AUDIT [SQLExecutionsAudit] TO FILE ( FILEPATH = N'C:\SQLServer\Audit\' ,MAXSIZE = 0 MB ,MAX_ROLLOVER_FILES = 2147483647 ,RESERVE_DISK_SPACE = OFF ) WITH ( QUEUE_DELAY = 1000 ,ON_FAILURE = CONTINUE ) GO
ALTER SERVER AUDIT [SQLExecutionsAudit] WITH (STATE = ON) GO
USE [XXX] GO
CREATE DATABASE AUDIT SPECIFICATION [DatabaseAuditSpec] FOR SERVER AUDIT [SQLExecutionsAudit] ADD (SELECT ON DATABASE::XXX BY [public]) WITH (STATE = ON) GO
你可以查询审计日志来获取SQL语句和用户信息:
SELECT FROM fn_get_auditfile('C:\SQLServer\Audit\SQLExecutionsAudit.sqlaudit', NULL, NULL)3. 第三方工具
有许多第三方工具(如ApexSQL、Redgate SQL Monitor等)可以提供更高级的监控和历史数据记录功能。这些工具通常可以捕获SQL语句、执行用户和其他相关信息,并提供详细的报告和分析功能。
结论
SQL Server的设计确实没有直接提供一个类似Oracle的v$sql视图来获取历史SQL执行者的信息。微软的设计可能基于性能和安全考虑,限制了历史数据的直接查询。然而,通过使用Extended Events、SQL Server Audit或第三方工具,你可以实现类似的功能。
希望这些建议能帮助你解决在SQL Server中获取历史SQL执行者的需求。如果你有进一步的问题或需要更详细的指导,请随时告诉我。











