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

时间:2013-07-26 06:10:05

标签: 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。

这将为我提供有关分析期间所涵盖代码百分比的Package明智信息。现在我试着看看这是否可以构建为一个正常的覆盖率报告,我可以知道哪一行代码被覆盖,哪一行不是(比如选择lineOfCode,来自...),这样我就可以用html构建一个报告格式化以指示是否覆盖了一行。

我对Oracle表结构并不太熟悉函数和程序保存的位置等。(从博客获得上述查询并稍微修改以删除运行ID)

这可能吗?

如果是这样我怎么能实现这个目标?

2 个答案:

答案 0 :(得分:1)

我认为接近之后的事情:

-- 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表中的许多行 NOT TOTAL_TIME列中都有准确的值,因为它们的执行速度比计时器的分辨率快。

Ask Tom re: timings

  

时间是使用某个时间单位收集的,通常只是   细化到HSECS。

     

这意味着许多离散事件的时间不到1/100   第二,似乎需要ZERO秒。

     

许多不到1/100秒的离散事件可能会发生   似乎需要1/100秒。

2)只有多行语句中的 FIRST 行才会显示为已覆盖。因此,如果您在多行中拆分INSERT或其他内容,我就不知道是否有任何简单的方法可以将该语句的每个行显示为Annotated Source样式中的profiled报告。

另外,请查看Oracle的dbms_profiler文档和this有用的软件包参考,以获取针对收集的分析器数据制作查询的帮助。

答案 1 :(得分:0)

实际上有一些PL / SQL工具可以进行代码覆盖。有关详细信息,请参阅此question的答案。

说,您可以在下表中找到有关用户创建的数据结构和代码的信息:

  • user_source:您可以在TEXT字段中找到以功能,程序,包装等为代表的来源。
  • User_tables
  • user_indexes
  • user_types:如果您使用某种OO代码。
  • 您可能需要的以user_开头的其他表格。

基本上,您需要针对user_source检查查询结果,并从其他表中获取额外信息。