捕获单个SQL Select语句

时间:2015-07-30 10:38:10

标签: sql-server

Hello SQL程序员和Gurus

我已经编写SQL几年了,我一直想知道如何抓住用户每天对数据库执行的第一条SQL语句。 当用户点击F5时,用户可能会突出显示许多Select语句(一个接一个地执行),但我只想尝试获得第一个。

我已经做了几次努力,但是他们回复太多请看。

实施例A. ..

string filePath = HttpContext.Server.MapPath($"~/App_Data/{Guid.NewGuid()}.xlsx");

---------------------------------------------- < / H2>

执行时返回所有这些。 ..

SELECT 'blah from first select' 
SELECT 'blah from second select' 

DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = @@SPID
SELECT  TEXT 
FROM sys.dm_exec_sql_text(@sqltext)

但我想要的结果只是DB执行的第一个select语句.. .. '从第一次选择&#39;'

中选择&#39;等等

可能会运行许多长而复杂的select语句(在批处理中),但我只需要执行第一个完整的SQL语句字符串。

- ============================================= ===

实施例B. ..

‘SELECT 'blah from first select' 
 SELECT 'blah from second select' 

DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = @@SPID
SELECT  TEXT 
FROM sys.dm_exec_sql_text(@sqltext)’

----------------------------------------------- -

这句话会返回一些行,但即使你拿到第一行也是如此。 ..

SELECT 'blah from first select' 
SELECT 'blah from second select' 

SELECT execquery.last_execution_time AS [Date Time], execsql.text AS [Script] FROM sys.dm_exec_query_stats AS execquery
CROSS APPLY sys.dm_exec_sql_text(execquery.sql_handle) AS execsql
--  where execsql.text like '%MHD%'
ORDER BY execquery.last_execution_time DESC

我真正想要的结果是。 .. '首先选择&#39;从第一次选择&#39;

任何人都可以帮忙吗? 我希望自己能够很好地解释自己,并且有人可以提供帮助,并希望通过这个小小的谜题获得乐趣。

干杯nosinet

1 个答案:

答案 0 :(得分:0)

以下是XE跟踪的示例:

CREATE EVENT SESSION [FirstStatementTrace] ON SERVER 
ADD EVENT sqlserver.sp_statement_starting(
    ACTION(package0.collect_system_time,package0.event_sequence,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)),
ADD EVENT sqlserver.sql_batch_starting(
    ACTION(package0.collect_system_time,package0.event_sequence,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)) 
ADD TARGET package0.event_file(SET filename=N'FirstStatementTrace')
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 [FirstStatementTrace] ON SERVER STATE = START;
GO

这是一个如何从跟踪数据中提取信息的示例。从性能角度来看,还有很大的提升空间,但我现在没时间调整它。不过,这应该可以让你开始。

IF OBJECT_ID(N'tempdb..#shredded_event_data', 'U') IS NOT NULL
    DROP TABLE #shredded_event_data;
GO

WITH 
    event_data AS (
        SELECT
            object_name, CAST(event_data AS xml) AS event_data_xml
        FROM sys.fn_xe_file_target_read_file ( N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Log\FirstStatementTrace*.xel', NULL, DEFAULT, DEFAULT )
    )
    , shredded_event_data AS (
        SELECT 
              object_name
            , event_data_xml.value('/event[1]/action[@name="collect_system_time"][1]/value[1]', 'datetime2(3)') AS collect_system_time
            , event_data_xml.value('/event[1]/action[@name="event_sequence"][1]/value[1]', 'bigint') AS event_sequence
            , event_data_xml.value('/event[1]/action[@name="client_app_name"][1]/value[1]', 'sysname') AS client_app_name
            , event_data_xml.value('/event[1]/action[@name="client_hostname"][1]/value[1]', 'sysname') AS client_hostname
            , event_data_xml.value('/event[1]/action[@name="session_id"][1]/value[1]', 'smallint') AS session_id
            , event_data_xml.value('/event[1]/action[@name="sql_text"][1]/value[1]', 'nvarchar(MAX)') AS sql_text
        FROM event_data
    )
SELECT
      collect_system_time
    , event_sequence
    , client_app_name
    , client_hostname
    , session_id
    , sql_text
    , ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY event_sequence) AS row_num
INTO #shredded_event_data
FROM shredded_event_data;