10

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

这可能吗?

如果是这样,我该如何实现?

4

2 回答 2

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

有几个问题要记住。

plsql_profiler_data1)表中的许多行在其列中不会有准确的值,TOTAL_TIME因为它们的执行速度比计时器的分辨率快。

问汤姆重新:时间

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

这意味着许多耗时不到 1/100 秒的离散事件似乎需要零秒。

许多耗时不到 1/100 秒的离散事件可能看起来耗时 1/100 秒。

2) 只有多行语句中的第一行才会显示为已覆盖。因此,如果您将一个INSERT或任何内容拆分为多行,我不知道有任何简单的方法可以将该语句的每一行显示为带注释的源样式的报告中的配置文件。

此外,请查看 Oracle 的dbms_profiler文档和这个有用的包参考,以帮助对收集的分析器数据进行查询。

于 2013-08-30T13:10:07.400 回答
0

实际上有一些用于 PL/SQL 的工具可以进行代码覆盖。有关更多信息,请参阅此问题的答案。

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

  • user_source: 在这里你可以在TEXT以函数、过程、包等为代表的字段中找到源代码。
  • User_tables
  • user_indexes
  • user_types: 如果你使用某种面向对象的代码。
  • user_以您可能需要的开头的其他表格。

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

于 2013-07-26T06:59:46.110 回答