我使用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)
这可能吗?
如果是这样我怎么能实现这个目标?
答案 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
列中都有准确的值,因为它们的执行速度比计时器的分辨率快。
时间是使用某个时间单位收集的,通常只是 细化到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
检查查询结果,并从其他表中获取额外信息。