如何在过程中执行提交的sql语句(作为参数)并测量执行时间?

des*_*iny 0 oracle plsql oracle11g

我想在PL/SQL中编写一个函数,它有一个sql语句作为参数.该语句可以是DDL,DML和DCL

我想从控制台中执行的语句打印时间.

我有以下代码:

 create or replace procedure measureTime (statement  IN varchar2 )AS 
--declarations
neededTime INTEGER;
  BEGIN 
    dbms_output.enable; 
    EXECUTE IMMEDIATE statement
 COMMIT; 
SELECT ELAPSED_TIME AS neededTime FROM V_$SQL WHERE SQL_TEXT=statement
    dbms_output.put_line('executeTime '|| neededTime);
 END measureTime;
Run Code Online (Sandbox Code Playgroud)

但它不起作用.怎么了?

Ben*_*Ben 5

有一种更简单的方法可以做到这一点; 只需在开始前取出开始时间,然后在完成后取消当前时间.

 create or replace procedure measureTime (statement  IN varchar2 )AS 

   l_start_time timestamp default systimestamp;

  BEGIN

    dbms_output.enable;

    EXECUTE IMMEDIATE statement;
    COMMIT; 

    dbms_output.put_line('executeTime '|| systimestamp - l_start_time);

  END measureTime;
Run Code Online (Sandbox Code Playgroud)

或者,如果你想要它在几秒钟内说systimestamp - l_start_time改为trunc((systimestamp - l_start_time) * 24 * 60 * 60)

这似乎是一种过度工作的方式.execute immediate因为Oracle必须在每次运行之前验证查询,所以会稍微慢一些.你为什么不只是执行查询?

commit还将致力于在那次会议上,你想要的东西可能不是已经发生的一切.

您还应确保已statement正确转义以避免SQL注入.

在回答你的问题时:

你的程序不会编译,因为你需要一个分号execute immediate.这应该被包括在参数statement.

您的选择语法也不正确.因为这是PL/SQL而不是SQL,所以你需要使用into子句,并且你在这个语句的末尾也缺少一个分号.

select elapsed_time 
  into neededTime 
  from v$sql 
 where sql_text = statement;
Run Code Online (Sandbox Code Playgroud)

即使没有语法错误,有几个原因你的语句可能不适合工作,例如,sql_textv$sql只有第1000个字符,因此,如果statement超过1K个字符长就没有比赛.如果您有一个group by子句,根据文档,不会存储统计信息.