作为存储过程要求的一部分,我需要提供特定子查询的开始和结束时间。例如,假设我的查询是:
SELECT price
FROM vehicles
WHERE wheels < 3
我的存储过程的输出应该是指向如下表的引用器:
price start_time end_time
12000 2018-08-08 08:42:31 2018-08-08 08:42:52
130000 2018-08-08 08:42:31 2018-08-08 08:42:52
6000 2018-08-08 08:42:31 2018-08-08 08:42:52
3500 2018-08-08 08:42:31 2018-08-08 08:42:52
其中start_time
是我启动选择语句的时间,而end_time
是它完成的时间。
我尝试了以下操作:
WITH start_time AS
( SELECT sysdate AS start_time
FROM dual
), main_query AS
( SELECT price
FROM vehicles
WHERE wheels < 3
), end_time AS
( SELECT sysdate AS end_time
FROM dual
)
SELECT main_query.*
, TO_CHAR(start_time, 'YYYY-MM-DD HH24:MI:SS') AS start_time
, TO_CHAR(end_time, 'YYYY-MM-DD HH24:MI:SS') AS end_time
FROM main_query
CROSS JOIN start_time
CROSS JOIN end_time
;
但是开始时间和结束时间都说相同的时间。
我知道这是一个非常规(且笨拙)的要求,但是需要必须...
答案 0 :(得分:4)
如果是过程的一部分,则让它分为两部分进行处理。首先,我们获取数据,然后将其返回。
我们创建一个对象来临时存储数据:
create type r_price_index as object (
price number(10,2));
create type t_price_index is table of r_price_index;
然后在您的proc中:
declare
v_price_index t_price_index;
v_t_stamp1 date;
v_t_stamp2 date;
v_cur sys_refcursor;
v_out sys_refcursor;
begin
v_t_stamp := sysdate; -- The start time
open v_cur for
SELECT price
FROM vehicles
WHERE wheels < 3;
fetch v_cure bulk collect into v_price_index; -- Store the data in the object
close v_cur;
v_t_stamp2 := sysdate; -- The end time
open v_out for -- Output the stored data
select price, v_t_stamp1 as s_time, v_t_stampt2 as e_time
from table(v_price_index);
end;
您需要进行一些异常处理(no_data_found等),但这应该可以为您提供所需的确切信息。
答案 1 :(得分:2)
在systimestamp
中使用函数sysdate
和SQL
的结果时会对其进行缓存,因此它们总是返回查询开始的时刻。
创建自定义函数my_timestamp
而不进行缓存,因此每次获取每一行都会调用一次。并且考虑到sysdate
具有第二精度,因此有机会错过快速查询的时间间隔。这就是systimestamp
对于基准测试更有用的原因。
取决于如何使用它,有时应用/*+ materialize */
提示以确保查询仅执行一次是很重要的,否则在较小的结果集上,优化器可能会决定多次运行子查询以产生时间结果不一致的。
with
function my_timestamp return timestamp is begin return systimestamp; end;
main_query AS (
SELECT /*+ materialize */
my_timestamp AS custom_ts,
systimestamp AS standard_ts,
T.*
FROM vehicles T
)
select (select max(custom_ts) from main_query) as end_time,
(select min(custom_ts) from main_query) as begin_time,
T.*
from main_query T;
PS。另外,使用a look at dbms_utility.get_time
函数来测量代码执行时间。