oracle - 使用 DBMS Profiler 构建 PL/SQL 覆盖率报告

标签 oracle plsql code-coverage profiler

我正在使用 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/

相关文章:

oracle - 如何知道我的Oracle系统是否设置为支持Unicode或多字节字符?

json - 如何在 PL/SQL 中解析 JSON 字符串

azure - coverlet 不会在 azure devops 中创建报告

mysql - SQL根据列的计数进行分组

sql - Oracle 从 1 开始序列

sql - 创建触发器时出现 Oracle 错误

SQL:将计数与 Clob 结合使用

regex - 为什么这个 Oracle regexp_like 测试为 FALSE?

unit-testing - 暂时获得 Jest 报道,只显示特定文件夹中的文件

java - Java EE 容器上的三叶草