awrsqrpt.sql报ora-01422因非交互环境误解析提示;须在sql*plus中set verify off/feedback off后手动执行;sql id须从dba_hist_sqlstat查,禁用v$sql模糊匹配;html乱码应转码或改用text模式;报告聚合不校验每快照执行情况,定位问题需先查具体snap_id。
awrsqrpt.sql 为什么总报错 ora-01422:exact fetch returns more than requested number of rows
这是最常卡住人的地方——awrsqrpt.sql 默认走交互式输入,但一旦在非 sql*plus 环境(比如某些自动化脚本、sql developer 的“运行脚本”模式)里执行,它会把后续的 prompt 当作 sql 执行,导致解析失败,最终触发 ora-01422。
真正该做的不是改参数,而是绕过交互:
- 用
@?/rdbms/admin/awrsqrpt.sql启动前,先在 SQL*Plus 里显式设置SET VERIFY OFF和SET FEEDBACK OFF - 必须在 SQL*Plus 中运行,不能用
sqlplus -S / as sysdba @awrsqrpt.sql这类静默模式——它会跳过所有提示,直接崩 - 正确姿势是:先连进 SQL*Plus,再手动敲
@?/rdbms/admin/awrsqrpt.sql,然后按顺序填:报告类型(text/html)、DBID、实例号、快照范围、SQL ID
SQL ID 怎么准确提取?别靠 v$sql.text 模糊匹配
v$sql.text 里查到的 SQL 可能被截断、带换行或空格不一致,直接复制过去生成报告大概率找不到语句。AWR 里认的是归一化后的 sql_id,不是你眼见的“那条 SQL”。
稳妥办法只有一条路径:
- 从
dba_hist_sqlstat查,条件必须含sql_id+plan_hash_value+ 时间范围,例如:SELECT sql_id, plan_hash_value, executions_delta, elapsed_time_delta/1000000 et_sec FROM dba_hist_sqlstat WHERE sql_id = 'abc123xyz789' AND snap_id BETWEEN 12345 AND 12350;
- 如果还不确定 SQL ID,用
dba_hist_sqltext配合dbms_lob.substr(sql_text, 200, 1)看开头片段,再结合sql_id关联查 - 千万别用
SELECT sql_id FROM v$sql WHERE sql_text LIKE '%xxx%'——v$sql不是 AWR 快照源,内容随时被刷,且大小写、空格、注释都会影响匹配
生成 HTML 报告时中文乱码、表格错位怎么办
HTML 版报告默认用 ISO-8859-1 编码,Oracle 数据库字符集是 AL32UTF8 时,中文字段名、SQL 文本、等待事件全会变方块或折行异常。
这不是报告工具的问题,是输出管道没转义:
- 不要改
awrsqrpt.sql源码——它不读取 NLS_LANG,也不支持指定编码参数 - 生成完后用
iconv转码:iconv -f ISO-8859-1 -t UTF-8 awr_report.html > awr_report_utf8.html
- 更省事的是:全程用 text 模式生成(选 1),再用
less或 VS Code 查看,避免 HTML 渲染干扰;真要 HTML,就接受它只适合英文环境下的快速浏览
为什么指定快照范围后报告里还是出现无关 SQL?
awrsqrpt.sql 本质是“按 SQL ID 拉取该语句在指定快照区间内的所有性能聚合”,但它**不校验该 SQL 是否在每个快照里都真实执行过**。只要 AWR 在任一快照中捕获过这个 sql_id,整段区间内所有统计(哪怕只有 1 次执行)都会被塞进报告。
这会导致两个典型误判:
- 看到 “Avg Elapsed Time: 0.002s” 却发现 “Executions: 1”,其实是其余 99 个快照里没执行,平均值被稀释了
- 等待事件列表里出现
enq: TX - row lock contention,但实际只发生在第 12348 号快照,报告却平摊到整个区间,掩盖了尖峰时刻 - 对策很简单:先用
dba_hist_active_sess_history定位具体快照号:SELECT DISTINCT snap_id FROM dba_hist_active_sess_history WHERE sql_id = 'abc123xyz789' AND sample_time BETWEEN SYSDATE-1 AND SYSDATE;
再用这两个快照号精准生成报告
AWR 报告不是快照的简单拼接,它是按语句维度做跨快照聚合的统计视图。想定位单次慢执行,得先锁死快照号,再进去看细节——指望一份报告说清所有问题,本身就是对工具的误用。










