diff --git a/Apewer.Source/Source/ExecutingStatement.cs b/Apewer.Source/Source/ExecutingStatement.cs
new file mode 100644
index 0000000..c395851
--- /dev/null
+++ b/Apewer.Source/Source/ExecutingStatement.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace Apewer.Source
+{
+
+ /// 正在执行的 SQL 语句。
+ [Serializable]
+ public sealed class ExecutingStatement
+ {
+
+ ///
+ public long Session { get; set; }
+
+ ///
+ public string Status { get; set; }
+
+ ///
+ public long CpuTime { get; set; }
+
+ ///
+ public long LogicalReads { get; set; }
+
+ ///
+ public long Reads { get; set; }
+
+ ///
+ public long Writes { get; set; }
+
+ ///
+ public double ElapsedTime { get; set; }
+
+ ///
+ public string StatementText { get; set; }
+
+ ///
+ public string LoginName { get; set; }
+
+ ///
+ public string HostName { get; set; }
+
+ ///
+ public DateTime LoginTime { get; set; }
+
+ ///
+ public long OpenTransactionCount { get; set; }
+
+ }
+
+}
diff --git a/Apewer.Source/Source/SqlClient.cs b/Apewer.Source/Source/SqlClient.cs
index cb4fb2b..6a380c8 100644
--- a/Apewer.Source/Source/SqlClient.cs
+++ b/Apewer.Source/Source/SqlClient.cs
@@ -782,6 +782,65 @@ COLLATE Chinese_PRC_CI_AS
return $"[{vcolumn.Field}] {type}";
}
+ /// 查询正在执行的语句,按执行时长降序排序。
+ ///
+ ///
+ public static ExecutingStatement[] QueryExecutingStatement(SqlClient source, int top = 100)
+ {
+ if (source == null) throw new ArgumentNullException(nameof(source));
+
+ var sql = top > 0 ? $"select top {top}" : "select";
+ sql = sql + @"
+ s.session_id,
+ r.status,
+ r.cpu_time,
+ r.logical_reads,
+ r.reads,
+ r.writes,
+ r.total_elapsed_time / 1000.0 as 'seconds',
+ r.command,
+ substring(
+ st.text,
+ (r.statement_start_offset / 2) + 1,
+ ((case r.statement_end_offset when -1 then datalength(st.text) else r.statement_end_offset end - r.statement_start_offset) / 2) + 1
+ ) as statement_text,
+ s.login_name,
+ s.host_name,
+ s.login_time,
+ r.open_transaction_count
+from sys.dm_exec_sessions as s
+join sys.dm_exec_requests as r on r.session_id = s.session_id cross apply sys.dm_exec_sql_text(r.sql_handle) as st
+where r.session_id != @@spid
+order by r.cpu_time desc
+";
+
+ using (var query = source.Query(sql))
+ {
+ if (!query.Success) throw new SqlException(query);
+
+ var rows = query.Rows;
+ var records = new List(rows);
+ for (var i = 0; i < rows; i++)
+ {
+ var record = new ExecutingStatement();
+ record.Session = query.Int64(i, "session_id");
+ record.Status = query.Text(i, "status");
+ record.CpuTime = query.Int64(i, "cpu_time");
+ record.LogicalReads = query.Int64(i, "logical_reads");
+ record.Reads = query.Int64(i, "reads");
+ record.Writes = query.Int64(i, "writes");
+ record.ElapsedTime = query.Double(i, "seconds");
+ record.StatementText = query.Text(i, "statement_text");
+ record.LoginName = query.Text(i, "login_name");
+ record.HostName = query.Text(i, "host_name");
+ record.LoginTime = query.DateTime(i, "login_time").Value;
+ record.OpenTransactionCount = query.Int64(i, "open_transaction_count");
+ records.Add(record);
+ }
+ return records.ToArray();
+ }
+ }
+
#endregion
}