为何DBMS_PLSQL_CODE_COVERAGE不将IF-ELSIF-ELSE的ELSE块识别为基本块
PL/SQL 基本块定义与覆盖率统计异常说明
基本块的两类定义
Oracle 官方定义
基本块指 PL/SQL 代码中仅包含单入口、单出口的代码块。
通用公开定义
基本块是一组始终按顺序逐行执行的语句集合,特征为内部不包含任何跳转语句,执行过程中不存在分支或中断的可能,所有语句按出现顺序依次执行。
覆盖率统计异常现象
使用DBMS_PLSQL_CODE_COVERAGE包统计 PL/SQL 代码的块级覆盖率时,出现IF-ELSIF-ELSE 结构的 ELSE 块未被识别为基本块的异常。
测试样例1:普通IF-ELSE结构

统计结果第二列的0、1值代表对应基本块的覆盖情况,IF和ELSE分支均被识别为基本块,结果符合预期。
测试样例2:IF-ELSIF-ELSE结构

所有IF、ELSIF分支都被识别为基本块,但ELSE块未被识别为基本块。按照基本块定义,该结果意味着只要执行进入最后一个ELSIF块,ELSE部分就一定会被执行,会影响代码覆盖率统计的准确性,但实际运行逻辑显然不符合该规则。
相关背景说明
目前仅知DBMS_PLSQL_CODE_COVERAGE包底层基于DBMS_PROFILER实现覆盖率统计,不了解其内部实现逻辑,需要该异常现象的成因解释。
覆盖率结果导出查询语句
SELECT LISTAGG(ccb.col, ',') WITHIN GROUP (ORDER BY ccb.col) AS col, LISTAGG(ccb.covered, ',') WITHIN GROUP (ORDER BY ccb.col) AS covered, s.line, LISTAGG(ccb.not_feasible, ',') WITHIN GROUP (ORDER BY ccb.col) AS not_feasible, s.text FROM user_source s JOIN dbmspcc_units ccu ON s.name = ccu.name AND s.type = ccu.type LEFT OUTER JOIN dbmspcc_blocks ccb ON ccu.run_id = ccb.run_id AND ccu.object_id = ccb.object_id AND s.line = ccb.line WHERE s.name = 'DEMO_UTILITY_TST' AND s.type = 'PACKAGE BODY' AND ccu.run_id = 248 GROUP BY s.line, s.text ORDER BY 3;
内容的提问来源于stack exchange,提问作者Buddhika Chathuranga
相关产品推荐
相关产品推荐

