暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 通过JAVA执行存储过程/包时,通过dbms_profiler进行代码覆盖

askTom 2017-02-27
257

问题描述

你好,汤姆,
发布相同的问题以及所要求的详细信息,因为我无权更新我以前的帖子。

我们试图找到java产品的plsql代码的代码覆盖范围,我们正在为此评估dbms_profiler。
这是我们面临的异常情况:

1.
通过JAVA执行存储过程时,我们不会在plsql_profiler_units中记录过程名称。
单元类型,单元名称和单元所有者所有3列显示: 匿名块!
而有多个包和程序正在执行!

2.
同样,对于同一测试,plsql_profiler_data中仅记录了1行代码,而正在执行多个软件包。

3.
通过后端运行dbms_profiler时 (直接从plsql developer调用过程),profiler覆盖率数据将未覆盖的行与所覆盖的行一起显示。

能否请你帮忙!

附加信息:

我们使用Spring framework的 “storedProcedure” 支持来调用数据库过程,该过程内部使用JDBC callalestatement,这里是代码供参考。用户在两种情况下都是相同的,即架构所有者


@ 覆盖
公共映射 <字符串,对象> 调用 (callaablestatementcreator csc,List declaredParameters)
抛出数据访问异常 {

final List updateCountParameters = new ArrayList();
final List resultSetParameters = new ArrayList();
final List callParameters = new ArrayList();
for (SqlParameter参数: declaredParameters) {
如果 (参数。isResultsParameter()) {
如果 (SqlReturnResultSet的参数实例) {
resultSetParameters.add (参数);
}
其他 {
updateCountParameters.add (参数);
}
}
其他 {
callParameters.add (参数);
}
}
返回执行 (csc,新的callaablestatementcallback >() {
@ 覆盖
公共映射 <字符串,对象> doincallalestatement (callalestatement cs) 抛出SQLException {
boolean retVal = cs.exe可爱 ();
int updateCount = cs.getUpdateCount();
if (记录器.isDebugEnabled()) {
logger.de bug("CallableStatement.exe可爱 () 返回 '" retVal "'");
logger.de bug (“CallableStatement.getUpdateCount() 返回” updateCount);
}
Map <字符串,对象> 返回结果 = createResultsMap();
如果 (retVal | | updateCount != -1) {
Returnedresult.putAll (extractreturnedresult (cs,updateCountParameters,resultSetParameters,updateCount));
}
returnedResults.putAll(extractOutputParameters(cs,callParameters));
返回返回结果;
}
});
}



专家解答

我对Spring不太了解,但是在探查器方面,Java和db之间没有任何固有的限制。这是我用的一个例子

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.time.ZonedDateTime;
import oracle.jdbc.internal.OraclePreparedStatement;
import java.sql.CallableStatement;

public class CallPLSQL {
     public static void main(String[] args) {
         Connection con = null;
         Statement stmt = null;
         ResultSet rs = null;
         try {
             Class.forName("oracle.jdbc.driver.OracleDriver");
             con =  DriverManager.getConnection("jdbc:oracle:thin:scott/tiger@//localhost:1521/db122");
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             e.printStackTrace();
         }

         try {

//             OraclePreparedStatement pstmt = (OraclePreparedStatement)con.prepareStatement(
//      "declare l_result int; begin l_result := dbms_profiler.start_profiler(run_comment=>'proc2');  my_proc;  l_result := dbms_profiler.stop_profiler; end;"
//                 );

            CallableStatement pstmt = con.prepareCall (
      "declare l_result int; begin l_result := dbms_profiler.start_profiler(run_comment=>'proc1');  my_proc;  l_result := dbms_profiler.stop_profiler; end;"
     );

             boolean done;
             done = pstmt.execute();

             System.out.print("Done");

         } catch (SQLException e) {
             e.printStackTrace();
         }
     }
}


复制


您可以看到我同时试用了OraclePreStatement和callable statement。

MY_PROC是一个简单的proc,它可以做一些事情,也可以调用MY_FUNC,只是为了看看我们可以收集什么。这是我从侧写器那里得到的

SQL> select runid,
  2         run_date,
  3         run_comment,
  4         run_total_time
  5  from   plsql_profiler_runs
  6  order by runid;

 RUNID RUN_DATE  RUN_COMMENT                                        RUN_TOTAL_TIME
------ --------- -------------------------------------------------- --------------
     6 24-MAR-17 proc1                                                  6000000000

1 row selected.

SQL>
SQL> select u.runid,
  2         u.unit_number,
  3         u.unit_type,
  4         u.unit_owner,
  5         u.unit_name,
  6         d.line#,
  7         d.total_occur,
  8         d.total_time,
  9         d.min_time,
 10         d.max_time
 11  from   plsql_profiler_units u
 12         join plsql_profiler_data d on u.runid = d.runid and u.unit_number = d.unit_number
 13  order by u.unit_number, d.line#;

 RUNID UNIT_NUMBER UNIT_TYPE            UNIT_OWNER           UNIT_NAME                           LINE# TOTAL_OCCUR TOTAL_TIME   MIN_TIME   MAX_TIME
------ ----------- -------------------- -------------------- ------------------------------ ---------- ----------- ---------- ---------- ----------
     6           1 ANONYMOUS BLOCK                                             1           3      21959        998      16968
     6           2 PROCEDURE            MCDONAC              MY_PROC                                 1           0        998        998        998
     6           2 PROCEDURE            MCDONAC              MY_PROC                                 4           1  438946047  438946047  438946047
     6           2 PROCEDURE            MCDONAC              MY_PROC                                 5           1    1581068    1581068    1581068
     6           2 PROCEDURE            MCDONAC              MY_PROC                                 7           1  474409287  474409287  474409287
     6           2 PROCEDURE            MCDONAC              MY_PROC                                 8           1    1643951    1643951    1643951
     6           2 PROCEDURE            MCDONAC              MY_PROC                                10           1      51903        998      50905
     6           2 PROCEDURE            MCDONAC              MY_PROC                                12          21       5988          0        998
     6           2 PROCEDURE            MCDONAC              MY_PROC                                13          20      92827        998      58890
     6           2 PROCEDURE            MCDONAC              MY_PROC                                15           1        998        998        998
     6           3 FUNCTION             MCDONAC              MY_FUNC                                 1           0      27948       1996       2994
     6           3 FUNCTION             MCDONAC              MY_FUNC                                 4          20   92177072    3677181    5906048
     6           3 FUNCTION             MCDONAC              MY_FUNC                                 5          20       9981          0        998
     6           3 FUNCTION             MCDONAC              MY_FUNC                                 6          20      31940        998       2994

复制


所以我们绝对可以跟踪调用,即使它们来自Java。如果您仍然遇到困难,我认为您需要在支持下记录通话,并为他们提供可复制的测试用例。

让我们知道你怎么走
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论