我正在使用 DBMS_PROFILER用于对我的 PL/SQL 包进行基本分析。我还使用它通过以下查询获取代码覆盖率统计信息:
SELECT EXEC.unit_name unitname,ROUND (EXEC.cnt/total.cnt * 100, 1) Code_coverage FROM
(SELECT u.unit_name, COUNT(1) cnt FROM plsql_profiler_data d, plsql_profiler_units u WHERE u.unit_number = d.unit_number GROUP BY u.unit_name) total,
(SELECT u.unit_name, COUNT(1) cnt FROM plsql_profiler_data d, plsql_profiler_units u WHERE u.unit_number = d.unit_number AND d.total_occur > 0 GROUP BY u.unit_name) EXEC
WHERE EXEC.unit_name = total.unit_name
我在每个分析器运行之前清除了 plsql_profiler_data,plsql_profiler_units,plsql_profiler_runs 表,这样我就不需要每次都知道运行 ID。
这将为我提供有关分析期间覆盖的代码百分比的打包信息。现在我想看看这是否可以构建为一个普通的覆盖率报告,在那里我可以知道哪一行代码被覆盖了,哪一行没有被覆盖(比如选择 lineOfCode,被覆盖...),这样我就可以用 html 构建报告格式化以指示一行是否被覆盖。
我不太精通 Oracle 表结构,关于函数和过程的保存位置等。(从博客中获取上述查询并稍作修改以删除运行 ID)
这可能吗?
如果是这样,我怎样才能做到这一点?
最佳答案
我认为这接近你所追求的:
-- View lines of code profiled, along with run times, next to the complete, ordered source..
-- Provides an annotated view of profiled packages, procs, etc.
-- Only the first line of a multiline SQL statement will register with timings.
SELECT u.UNIT_OWNER || '.' || u.UNIT_NAME AS "Unit"
, s.line
, CASE WHEN d.TOTAL_OCCUR >= 0 THEN 'C'
ELSE ' ' END AS Covered
, s.TEXT
, TO_CHAR(d.TOTAL_TIME / (1000*1000*1000), 'fm990.000009') AS "Total Time (sec)"
, CASE WHEN NVL(d.TOTAL_OCCUR, 1) > 0 THEN d.TOTAL_OCCUR ELSE 1 END AS "# Iterations"
, TO_CHAR(CASE WHEN d.TOTAL_OCCUR > 0 THEN d.TOTAL_TIME / (d.TOTAL_OCCUR * (1000*1000*1000))
ELSE NULL END, 'fm990.000009') AS "Avg Time (sec)"
FROM all_source s
LEFT JOIN plsql_profiler_units u ON s.OWNER = u.UNIT_OWNER
AND s.NAME = u.UNIT_NAME
AND s.TYPE = u.UNIT_TYPE
LEFT JOIN plsql_profiler_data d ON u.UNIT_NUMBER = d.UNIT_NUMBER
AND s.LINE = d.LINE#
AND d.RUNID = u.RUNID
WHERE u.RUNID = ? -- Add RUNID of profiler run to investigate here
ORDER BY u.UNIT_NAME
, s.LINE
要记住的问题很少。
1)
plsql_profiler_data
中有很多行表会不是 在他们的 TOTAL_TIME
中有准确的值列,因为它们的执行速度比计时器的分辨率快。Ask Tom re: timings :
The timings are collected using some unit of time, typically only granular to the HSECS.
That means that many discrete events that take less then 1/100th of a second, appear to take ZERO seconds.
Many discrete events that take less then 1/100ths of a second may appear to take 1/100th of a second.
2) 只有 第一 多行语句中的行将显示为已覆盖。因此,如果您拆分
INSERT
或跨多行的任何内容,我不知道有什么简单的方法可以让该语句的每一行显示为注释源样式的报告中的概要文件。另外,请查看 Oracle 的 dbms_profiler文档和 this有用的包引用,可帮助针对收集的探查器数据制作查询。
关于oracle - 使用 DBMS Profiler 构建 PL/SQL 覆盖率报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17874131/