Browse Source

增加 SqlClient,用于查询正在执行的语句。

master
王厅 5 days ago
parent
commit
38e00f5cb8
  1. 49
      Apewer.Source/Source/ExecutingStatement.cs
  2. 59
      Apewer.Source/Source/SqlClient.cs

49
Apewer.Source/Source/ExecutingStatement.cs

@ -0,0 +1,49 @@
using System;
namespace Apewer.Source
{
/// <summary>正在执行的 SQL 语句。</summary>
[Serializable]
public sealed class ExecutingStatement
{
/// <summary></summary>
public long Session { get; set; }
/// <summary></summary>
public string Status { get; set; }
/// <summary></summary>
public long CpuTime { get; set; }
/// <summary></summary>
public long LogicalReads { get; set; }
/// <summary></summary>
public long Reads { get; set; }
/// <summary></summary>
public long Writes { get; set; }
/// <summary></summary>
public double ElapsedTime { get; set; }
/// <summary></summary>
public string StatementText { get; set; }
/// <summary></summary>
public string LoginName { get; set; }
/// <summary></summary>
public string HostName { get; set; }
/// <summary></summary>
public DateTime LoginTime { get; set; }
/// <summary></summary>
public long OpenTransactionCount { get; set; }
}
}

59
Apewer.Source/Source/SqlClient.cs

@ -782,6 +782,65 @@ COLLATE Chinese_PRC_CI_AS
return $"[{vcolumn.Field}] {type}"; return $"[{vcolumn.Field}] {type}";
} }
/// <summary>查询正在执行的语句,按执行时长降序排序。</summary>
/// <exception cref="ArgumentNullException" />
/// <exception cref="SqlException" />
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<ExecutingStatement>(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 #endregion
} }

Loading…
Cancel
Save