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 }