
方法一:使用sqlcmd
bash
C:\>sqlcmd -S LAPTOP-25D4U18P -i C:\sqlserver_check_html.sql -o C:\check\report.html -h-1 -f 65001
sqlserver_check_html.sql代码如下:
bash
SET NOCOUNT ON;
-- 修复错误的关键设置
SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET CONCAT_NULL_YIELDS_NULL ON;
DECLARE @html NVARCHAR(MAX) = N'';
DECLARE @report_title NVARCHAR(255) = 'SQL Server 健康检查报告';
DECLARE @servername NVARCHAR(128) = @@SERVERNAME;
DECLARE @current_time NVARCHAR(30) = CONVERT(NVARCHAR(30), GETDATE(), 120);
-- 创建HTML头部
SET @html = N'<!DOCTYPE html><html><head><meta charset="UTF-8"><title>'
+ @report_title
+ N'</title><style>body{font-family:"Segoe UI",Arial,sans-serif;margin:20px;background:#f5f7fa;color:#333}.container{max-width:1200px;margin:0 auto}.header{background:linear-gradient(135deg,#0066cc,#003366);color:white;padding:25px;border-radius:8px;margin-bottom:25px;box-shadow:0 4px 12px rgba(0,0,0,0.1)}.header h1{margin:0;font-size:28px}.header p{margin:5px 0 0;opacity:0.9}.card{background:white;border-radius:8px;padding:20px;margin-bottom:20px;box-shadow:0 2px 10px rgba(0,0,0,0.05);border-left:4px solid #0066cc;transition:transform 0.3s}.card:hover{transform:translateY(-3px);box-shadow:0 5px 15px rgba(0,0,0,0.1)}.card h2{color:#0066cc;margin-top:0;padding-bottom:10px;border-bottom:1px solid #eee;font-size:20px}table{width:100%;border-collapse:collapse;margin-top:15px}th{background:#e6f2ff;text-align:left;padding:12px 15px;font-weight:600;color:#004d99}td{padding:10px 15px;border-bottom:1px solid #eee}tr:nth-child(even){background-color:#f9fbfd}tr:hover{background-color:#f0f7ff}.warning{color:#e74c3c;font-weight:600}.footer{text-align:center;margin-top:30px;padding:20px;color:#777;font-size:14px;border-top:1px solid #eee}.section-title{display:flex;align-items:center;margin-bottom:15px}.section-title:before{content:"■";color:#0066cc;margin-right:10px;font-size:18px}</style></head><body><div class="container"><div class="header"><h1>'
+ @report_title
+ N'</h1><p>服务器: '
+ @servername
+ N' | 生成时间: '
+ @current_time
+ N'</p></div>';
-- 1. 数据库版本信息
SET @html = @html + N'<div class="card"><div class="section-title"><h2>1. 数据库版本信息</h2></div><table><tr><th>属性</th><th>值</th></tr><tr><td>SQL Server 版本</td><td>'
+ CAST(REPLACE(REPLACE(@@VERSION, CHAR(13), ''), CHAR(10), '<br>') AS NVARCHAR(MAX))
+ N'</td></tr><tr><td>产品版本</td><td>'
+ CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128))
+ N'</td></tr><tr><td>版本</td><td>'
+ CAST(SERVERPROPERTY('Edition') AS NVARCHAR(128))
+ N'</td></tr><tr><td>Service Pack</td><td>'
+ CAST(SERVERPROPERTY('ProductLevel') AS NVARCHAR(128))
+ N'</td></tr></table></div>';
-- 2. 最大连接数
SET @html = @html + N'<div class="card"><div class="section-title"><h2>2. 最大连接数</h2></div><table><tr><th>参数</th><th>值</th></tr><tr><td>最大连接数</td><td>'
+ CAST(@@MAX_CONNECTIONS AS NVARCHAR(20))
+ N'</td></tr></table></div>';
-- 3. 活动用户会话 - 修复FOR XML PATH选项问题
DECLARE @sessions_html NVARCHAR(MAX) = N'';
SELECT @sessions_html = @sessions_html +
N'<tr>' +
N'<td>' + CAST(session_id AS NVARCHAR(10)) + N'</td>' +
N'<td>' + ISNULL(login_name, '') + N'</td>' +
N'<td>' + ISNULL(host_name, '') + N'</td>' +
N'<td>' + ISNULL(program_name, '') + N'</td>' +
N'<td>' + ISNULL(status, '') + N'</td>' +
N'</tr>'
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>3. 活动用户会话</h2></div><table><tr><th>会话ID</th><th>登录名</th><th>主机名</th><th>程序名称</th><th>状态</th></tr>'
+ @sessions_html
+ N'</table></div>';
-- 4. 数据库大小信息
DECLARE @dbsize_html NVARCHAR(MAX) = N'';
SELECT @dbsize_html = @dbsize_html +
N'<tr>' +
N'<td>' + d.name + N'</td>' +
N'<td>' + CAST(ROUND(SUM(mf.size) * 8 / 1024.0, 2) AS NVARCHAR(20)) + N' MB</td>' +
N'<td>' + d.state_desc + N'</td>' +
N'<td>' + d.recovery_model_desc + N'</td>' +
N'</tr>'
FROM sys.databases d
JOIN sys.master_files mf ON d.database_id = mf.database_id
GROUP BY d.name, d.state_desc, d.recovery_model_desc;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>4. 数据库大小信息</h2></div><table><tr><th>数据库名称</th><th>大小 (MB)</th><th>状态</th><th>恢复模式</th></tr>'
+ @dbsize_html
+ N'</table></div>';
-- 5. 磁盘空间信息
CREATE TABLE #drives (drive CHAR(1), free_mb INT);
INSERT INTO #drives EXEC master.dbo.xp_fixeddrives;
DECLARE @disks_html NVARCHAR(MAX) = N'';
SELECT @disks_html = @disks_html +
N'<tr>' +
N'<td>' + drive + N':</td>' +
N'<td>' + CAST(CAST(free_mb/1024.0 AS DECIMAL(10,2)) AS NVARCHAR(20)) + N' GB</td>' +
N'</tr>'
FROM #drives;
DROP TABLE #drives;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>5. 磁盘空间信息</h2></div><table><tr><th>驱动器</th><th>可用空间 (GB)</th></tr>'
+ @disks_html
+ N'</table></div>';
-- 6. 关键配置参数
DECLARE @config_html NVARCHAR(MAX) = N'';
SELECT @config_html = @config_html +
N'<tr>' +
N'<td>' + name + N'</td>' +
N'<td>' + CAST(value AS NVARCHAR(50)) + N'</td>' +
N'<td>' + CAST(value_in_use AS NVARCHAR(50)) + N'</td>' +
N'</tr>'
FROM sys.configurations
WHERE name IN (
'max server memory (MB)',
'min server memory (MB)',
'max degree of parallelism',
'cost threshold for parallelism',
'backup compression default'
);
SET @html = @html + N'<div class="card"><div class="section-title"><h2>6. 关键配置参数</h2></div><table><tr><th>参数名</th><th>当前值</th><th>运行值</th></tr>'
+ @config_html
+ N'</table></div>';
-- 7. 数据库状态概览
DECLARE @dbstatus_html NVARCHAR(MAX) = N'';
SELECT @dbstatus_html = @dbstatus_html +
N'<tr>' +
N'<td>' + name + N'</td>' +
N'<td>' + state_desc + N'</td>' +
N'<td>' + recovery_model_desc + N'</td>' +
N'<td>' + CAST([compatibility_level] AS NVARCHAR(10)) + N'</td>' +
N'</tr>'
FROM sys.databases;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>7. 数据库状态概览</h2></div><table><tr><th>数据库</th><th>状态</th><th>恢复模式</th><th>兼容级别</th></tr>'
+ @dbstatus_html
+ N'</table></div>';
-- 8. 等待统计信息
DECLARE @waits_html NVARCHAR(MAX) = N'';
SELECT @waits_html = @waits_html +
N'<tr>' +
N'<td>' + wait_type + N'</td>' +
N'<td>' + CAST(wait_time_ms AS NVARCHAR(50)) + N'</td>' +
N'<td>' + CAST(waiting_tasks_count AS NVARCHAR(50)) + N'</td>' +
N'</tr>'
FROM (
SELECT TOP 10 wait_type, wait_time_ms, waiting_tasks_count
FROM sys.dm_os_wait_stats
WHERE wait_time_ms > 0
ORDER BY wait_time_ms DESC
) AS waits;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>8. 等待统计信息 (TOP 10)</h2></div><table><tr><th>等待类型</th><th>等待时间 (ms)</th><th>等待任务数</th></tr>'
+ @waits_html
+ N'</table></div>';
-- 9. CPU使用情况
SET @html = @html + N'<div class="card"><div class="section-title"><h2>9. CPU使用情况</h2></div><table><tr><th>指标</th><th>值</th></tr><tr><td>CPU繁忙时间</td><td>'
+ CAST(@@CPU_BUSY AS NVARCHAR(50))
+ N' 毫秒</td></tr><tr><td>CPU空闲时间</td><td>'
+ CAST(@@IDLE AS NVARCHAR(50))
+ N' 毫秒</td></tr><tr><td>总CPU时间</td><td>'
+ CAST(@@TIMETICKS AS NVARCHAR(50))
+ N' 微秒/时钟周期</td></tr></table></div>';
-- 10. 阻塞进程
DECLARE @blocks_html NVARCHAR(MAX) = N'';
SELECT @blocks_html = @blocks_html +
N'<tr>' +
N'<td>' + CAST(session_id AS NVARCHAR(20)) + N'</td>' +
N'<td>' + CAST(blocking_session_id AS NVARCHAR(20)) + N'</td>' +
N'<td>' + CAST(wait_duration_ms AS NVARCHAR(20)) + N'</td>' +
N'<td>' + ISNULL(wait_type, '') + N'</td>' +
N'</tr>'
FROM sys.dm_os_waiting_tasks
WHERE blocking_session_id <> 0;
SET @html = @html + N'<div class="card"><div class="section-title"><h2>10. 阻塞进程</h2></div><table><tr><th>被阻塞会话</th><th>阻塞会话</th><th>等待时间 (ms)</th><th>等待类型</th></tr>'
+ @blocks_html
+ N'</table></div>';
-- 完成HTML文档
SET @html = @html + N'<div class="footer"><p>报告生成时间: '
+ @current_time
+ N'</p><p>© SQL Server 健康检查报告 - 自动生成</p></div></div></body></html>';
-- 分段输出避免截断
DECLARE @ChunkSize INT = 4000;
DECLARE @StartIndex INT = 1;
DECLARE @EndIndex INT = @ChunkSize;
DECLARE @TotalLength INT = LEN(@html);
WHILE @StartIndex <= @TotalLength
BEGIN
IF @EndIndex > @TotalLength
SET @EndIndex = @TotalLength;
PRINT SUBSTRING(@html, @StartIndex, @EndIndex - @StartIndex + 1);
SET @StartIndex = @EndIndex + 1;
SET @EndIndex = @StartIndex + @ChunkSize - 1;
END;
方法二:直接复制在MSSM工具执行
bash
SET NOCOUNT ON;
DECLARE @html NVARCHAR(MAX) = N''
DECLARE @report_title NVARCHAR(255) = 'SQL Server 健康检查报告'
DECLARE @servername NVARCHAR(128) = @@SERVERNAME
DECLARE @current_time NVARCHAR(30) = CONVERT(NVARCHAR(30), GETDATE(), 120)
-- 创建HTML头部
SET @html = N'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>' + @report_title + N'</title>
<style>
body { font-family: "Segoe UI", Arial, sans-serif; margin: 20px; background: #f5f7fa; color: #333; }
.container { max-width: 1200px; margin: 0 auto; }
.header { background: linear-gradient(135deg, #0066cc, #003366); color: white; padding: 25px; border-radius: 8px; margin-bottom: 25px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.header h1 { margin: 0; font-size: 28px; }
.header p { margin: 5px 0 0; opacity: 0.9; }
.card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); border-left: 4px solid #0066cc; transition: transform 0.3s; }
.card:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0,0,0,0.1); }
.card h2 { color: #0066cc; margin-top: 0; padding-bottom: 10px; border-bottom: 1px solid #eee; font-size: 20px; }
table { width: 100%; border-collapse: collapse; margin-top: 15px; }
th { background: #e6f2ff; text-align: left; padding: 12px 15px; font-weight: 600; color: #004d99; }
td { padding: 10px 15px; border-bottom: 1px solid #eee; }
tr:nth-child(even) { background-color: #f9fbfd; }
tr:hover { background-color: #f0f7ff; }
.warning { color: #e74c3c; font-weight: 600; }
.footer { text-align: center; margin-top: 30px; padding: 20px; color: #777; font-size: 14px; border-top: 1px solid #eee; }
.section-title { display: flex; align-items: center; margin-bottom: 15px; }
.section-title:before { content: "■"; color: #0066cc; margin-right: 10px; font-size: 18px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>' + @report_title + N'</h1>
<p>服务器: ' + @servername + N' | 生成时间: ' + @current_time + N'</p>
</div>';
-- 1. 数据库版本信息
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>1. 数据库版本信息</h2></div>
<table>
<tr><th>属性</th><th>值</th></tr>
<tr><td>SQL Server 版本</td><td>' + CAST(@@VERSION AS NVARCHAR(500)) + N'</td></tr>
<tr><td>产品版本</td><td>' + CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)) + N'</td></tr>
<tr><td>版本</td><td>' + CAST(SERVERPROPERTY('Edition') AS NVARCHAR(128)) + N'</td></tr>
<tr><td>Service Pack</td><td>' + CAST(SERVERPROPERTY('ProductLevel') AS NVARCHAR(128)) + N'</td></tr>
</table>
</div>';
-- 2. 最大连接数
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>2. 最大连接数</h2></div>
<table>
<tr><th>参数</th><th>值</th></tr>
<tr><td>最大连接数</td><td>' + CAST(@@MAX_CONNECTIONS AS NVARCHAR(20)) + N'</td></tr>
</table>
</div>';
-- 3. 活动用户会话
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>3. 活动用户会话</h2></div>
<table>
<tr>
<th>会话ID</th>
<th>登录名</th>
<th>主机名</th>
<th>程序名称</th>
<th>状态</th>
</tr>';
DECLARE @session_id INT, @login_name NVARCHAR(128), @host_name NVARCHAR(128),
@program_name NVARCHAR(128), @status NVARCHAR(30)
DECLARE session_cursor CURSOR FOR
SELECT session_id, login_name, host_name, program_name, status
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
OPEN session_cursor
FETCH NEXT FROM session_cursor INTO @session_id, @login_name, @host_name, @program_name, @status
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + CAST(@session_id AS NVARCHAR(10)) + N'</td>
<td>' + ISNULL(@login_name, N'') + N'</td>
<td>' + ISNULL(@host_name, N'') + N'</td>
<td>' + ISNULL(@program_name, N'') + N'</td>
<td>' + ISNULL(@status, N'') + N'</td>
</tr>'
FETCH NEXT FROM session_cursor INTO @session_id, @login_name, @host_name, @program_name, @status
END
CLOSE session_cursor
DEALLOCATE session_cursor
SET @html = @html + N'</table></div>';
-- 4. 数据库大小信息
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>4. 数据库大小信息</h2></div>
<table>
<tr>
<th>数据库名称</th>
<th>大小 (MB)</th>
<th>状态</th>
<th>恢复模式</th>
</tr>';
DECLARE @dbname NVARCHAR(128), @dbsize_mb DECIMAL(18,2), @dbstate_desc NVARCHAR(60),
@recovery_model_desc NVARCHAR(60)
DECLARE db_cursor CURSOR FOR
SELECT
d.name,
SUM(mf.size) * 8 / 1024.0,
d.state_desc,
d.recovery_model_desc
FROM sys.databases d
JOIN sys.master_files mf ON d.database_id = mf.database_id
GROUP BY d.name, d.state_desc, d.recovery_model_desc
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbname, @dbsize_mb, @dbstate_desc, @recovery_model_desc
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + @dbname + N'</td>
<td>' + CAST(ROUND(@dbsize_mb, 2) AS NVARCHAR(20)) + N' MB</td>
<td>' + @dbstate_desc + N'</td>
<td>' + @recovery_model_desc + N'</td>
</tr>'
FETCH NEXT FROM db_cursor INTO @dbname, @dbsize_mb, @dbstate_desc, @recovery_model_desc
END
CLOSE db_cursor
DEALLOCATE db_cursor
SET @html = @html + N'</table></div>';
-- 5. 磁盘空间信息 (使用替代方法)
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>5. 磁盘空间信息</h2></div>
<table>
<tr>
<th>驱动器</th>
<th>可用空间 (GB)</th>
</tr>';
-- 使用sys.master_files估算磁盘空间
DECLARE @drive CHAR(1), @free_gb DECIMAL(10,2)
CREATE TABLE #drives (
drive CHAR(1) PRIMARY KEY,
total_size_gb DECIMAL(10,2),
used_size_gb DECIMAL(10,2)
)
INSERT INTO #drives (drive, total_size_gb, used_size_gb)
SELECT
LEFT(physical_name, 1) AS drive,
SUM(size) * 8.0 / 1024 / 1024 AS total_size_gb,
SUM(CAST(FILEPROPERTY(name, 'SpaceUsed') AS BIGINT)) * 8.0 / 1024 / 1024 AS used_size_gb
FROM sys.master_files
GROUP BY LEFT(physical_name, 1)
DECLARE drive_cursor CURSOR FOR
SELECT drive, total_size_gb - used_size_gb
FROM #drives
OPEN drive_cursor
FETCH NEXT FROM drive_cursor INTO @drive, @free_gb
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + @drive + N':</td>
<td>' + CAST(ROUND(@free_gb, 2) AS NVARCHAR(20)) + N' GB (估算值)</td>
</tr>'
FETCH NEXT FROM drive_cursor INTO @drive, @free_gb
END
CLOSE drive_cursor
DEALLOCATE drive_cursor
DROP TABLE #drives
SET @html = @html + N'</table>
<p class="warning">注意: 由于安全限制,无法获取精确的磁盘空间信息。以上为数据库文件占用空间的估算值。</p>
</div>';
-- 6. 关键配置参数
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>6. 关键配置参数</h2></div>
<table>
<tr>
<th>参数名</th>
<th>当前值</th>
<th>运行值</th>
</tr>';
DECLARE @config_name NVARCHAR(128), @config_value SQL_VARIANT, @value_in_use SQL_VARIANT
DECLARE config_cursor CURSOR FOR
SELECT name, value, value_in_use
FROM sys.configurations
WHERE name IN (
'max server memory (MB)',
'min server memory (MB)',
'max degree of parallelism',
'cost threshold for parallelism',
'backup compression default'
)
OPEN config_cursor
FETCH NEXT FROM config_cursor INTO @config_name, @config_value, @value_in_use
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + @config_name + N'</td>
<td>' + CAST(@config_value AS NVARCHAR(50)) + N'</td>
<td>' + CAST(@value_in_use AS NVARCHAR(50)) + N'</td>
</tr>'
FETCH NEXT FROM config_cursor INTO @config_name, @config_value, @value_in_use
END
CLOSE config_cursor
DEALLOCATE config_cursor
SET @html = @html + N'</table></div>';
-- 7. 数据库状态概览
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>7. 数据库状态概览</h2></div>
<table>
<tr>
<th>数据库</th>
<th>状态</th>
<th>恢复模式</th>
<th>兼容级别</th>
</tr>';
DECLARE @compatibility TINYINT
DECLARE db_state_cursor CURSOR FOR
SELECT name, state_desc, recovery_model_desc, [compatibility_level]
FROM sys.databases
OPEN db_state_cursor
FETCH NEXT FROM db_state_cursor INTO @dbname, @dbstate_desc, @recovery_model_desc, @compatibility
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + @dbname + N'</td>
<td>' + @dbstate_desc + N'</td>
<td>' + @recovery_model_desc + N'</td>
<td>' + CAST(@compatibility AS NVARCHAR(10)) + N'</td>
</tr>'
FETCH NEXT FROM db_state_cursor INTO @dbname, @dbstate_desc, @recovery_model_desc, @compatibility
END
CLOSE db_state_cursor
DEALLOCATE db_state_cursor
SET @html = @html + N'</table></div>';
-- 8. 等待统计信息
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>8. 等待统计信息 (TOP 10)</h2></div>
<table>
<tr>
<th>等待类型</th>
<th>等待时间 (ms)</th>
<th>等待任务数</th>
</tr>';
DECLARE @wait_type NVARCHAR(60), @wait_time BIGINT, @wait_count BIGINT
DECLARE wait_cursor CURSOR FOR
SELECT TOP 10 wait_type, wait_time_ms, waiting_tasks_count
FROM sys.dm_os_wait_stats
WHERE wait_time_ms > 0
ORDER BY wait_time_ms DESC
OPEN wait_cursor
FETCH NEXT FROM wait_cursor INTO @wait_type, @wait_time, @wait_count
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + @wait_type + N'</td>
<td>' + CAST(@wait_time AS NVARCHAR(50)) + N'</td>
<td>' + CAST(@wait_count AS NVARCHAR(50)) + N'</td>
</tr>'
FETCH NEXT FROM wait_cursor INTO @wait_type, @wait_time, @wait_count
END
CLOSE wait_cursor
DEALLOCATE wait_cursor
SET @html = @html + N'</table></div>';
-- 9. CPU使用情况
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>9. CPU使用情况</h2></div>
<table>
<tr>
<th>指标</th>
<th>值</th>
</tr>
<tr>
<td>CPU繁忙时间</td>
<td>' + CAST(@@CPU_BUSY AS NVARCHAR(50)) + N' 毫秒</td>
</tr>
<tr>
<td>CPU空闲时间</td>
<td>' + CAST(@@IDLE AS NVARCHAR(50)) + N' 毫秒</td>
</tr>
<tr>
<td>总CPU时间</td>
<td>' + CAST(@@TIMETICKS AS NVARCHAR(50)) + N' 微秒/时钟周期</td>
</tr>
</table>
</div>';
-- 10. 阻塞进程
SET @html = @html + N'
<div class="card">
<div class="section-title"><h2>10. 阻塞进程</h2></div>
<table>
<tr>
<th>被阻塞会话</th>
<th>阻塞会话</th>
<th>等待时间 (ms)</th>
<th>等待类型</th>
</tr>';
DECLARE @blocked_session INT, @blocking_session INT, @wait_duration BIGINT, @wait_type2 NVARCHAR(60)
DECLARE block_cursor CURSOR FOR
SELECT session_id, blocking_session_id, wait_duration_ms, wait_type
FROM sys.dm_os_waiting_tasks
WHERE blocking_session_id <> 0
OPEN block_cursor
FETCH NEXT FROM block_cursor INTO @blocked_session, @blocking_session, @wait_duration, @wait_type2
WHILE @@FETCH_STATUS = 0
BEGIN
SET @html = @html + N'
<tr>
<td>' + CAST(@blocked_session AS NVARCHAR(20)) + N'</td>
<td>' + CAST(@blocking_session AS NVARCHAR(20)) + N'</td>
<td>' + CAST(@wait_duration AS NVARCHAR(20)) + N'</td>
<td>' + @wait_type2 + N'</td>
</tr>'
FETCH NEXT FROM block_cursor INTO @blocked_session, @blocking_session, @wait_duration, @wait_type2
END
CLOSE block_cursor
DEALLOCATE block_cursor
SET @html = @html + N'</table></div>';
-- 完成HTML文档
SET @html = @html + N'
<div class="footer">
<p>报告生成时间: ' + @current_time + N'</p>
<p>© SQL Server 健康检查报告 - 自动生成</p>
<p class="warning">注意: 由于安全限制,某些信息可能为估算值或不完整</p>
</div>
</div>
</body>
</html>';
-- 输出HTML内容
SELECT @html AS [HTML-Report];
SELECT '由于安全限制,无法自动创建文件。请复制上方HTML内容,保存为.html文件后在浏览器中打开查看。' AS [操作说明];
