我有一个存储在Oracle DB表中的查询列表。我的要求是逐个获取每个查询并在过程中触发它们并在另一个表中记录它们的开始结束和已用时间
我的问题是我应该如何处理列列表,因为每个查询都会有所不同,并且在运行时无法预测列数及其数据类型。
请建议出路。
目前,我已经写下了以下代码。这里我附上了使用count()获取的每个查询以避免问题。但是,计数()查询所用的实际时间将与执行原始查询所用的时间不同。
非常感谢!
DECLARE
before_time TIMESTAMP;
after_time TIMESTAMP;
elapsed_time_in_ms NUMBER;
stmnt CLOB; --varchar(32000);
counts NUMBER;
sql_no NUMBER;
err_mess VARCHAR2(100);
CURSOR get_queries
IS
SELECT * FROM SLOW_RUNNING_SQL WHERE curr_ind = 1;
FUNCTION get_elapsed_time(
start_time_in TIMESTAMP ,
end_time_in TIMESTAMP )
RETURN NUMBER
AS
l_days NUMBER;
hours NUMBER;
minutes NUMBER;
seconds NUMBER;
milliseconds NUMBER;
BEGIN
<calculates elapsed time in milliseconds and returns that>
RETURN milliseconds ;
END;
BEGIN
dbms_output.put_line(CURRENT_TIMESTAMP);
before_time := SYSTIMESTAMP;
FOR i IN get_queries
LOOP
stmnt := i.SQL_DESC;
sql_no := i.sql_no;
stmnt := 'SELECT count(*) FROM ('||stmnt||') a';
dbms_output.put_line(stmnt);
EXECUTE IMMEDIATE stmnt INTO counts;
after_time := SYSTIMESTAMP;
elapsed_time_in_ms:= get_elapsed_time(before_time,after_time);
dbms_output.put_line(elapsed_time_in_ms);
INSERT
INTO query_performance_log VALUES
(
i.sql_no,
stmnt,
counts,
before_time,
after_time,
elapsed_time_in_ms/1000,
'No exception',
elapsed_time_in_ms );
dbms_output.put_line(stmnt);
dbms_output.put_line(counts);
dbms_output.put_line(after_time);
dbms_output.put_line(TO_CHAR(after_time - before_time));
COMMIT;
END LOOP;
ROLLBACK;
EXCEPTION
WHEN OTHERS THEN
err_mess:= SQLERRM;
INSERT
INTO query_performance_log VALUES
(
sql_no,
stmnt,
0,
NULL,
NULL,
0,
err_mess,
0
);
dbms_output.put_line(SQLERRM);
ROLLBACK;
END;
答案 0 :(得分:0)
可能适合您的解决方案是为查询返回的每一行选择一个常量,并生成bulk collect INTO
个varchar2
个变量的集合。
以下是您要找的内容:
-- declare a list of varchar2:
CREATE OR REPLACE TYPE t_my_list AS TABLE OF VARCHAR2(100);
-- then use this type in your proc.:
[..]
declare
v_res t_my_list;
[..]
-- then run the query
execute immediate 'SELECT ''x'' FROM ('||stmnt||') '
bulk collect into v_res;
如果您的查询选择的列“简单”,则上述内容应该足够公平以评估效果。但是如果你开始调用你在select
中检索的数据的其他函数和过程,那么它就更复杂了。
在另一种情况下,那么你应该尝试一些工作来构建返回列的串联(并在VARCHAR2(100)
的声明中放大t_my_list
)。这意味着您开始使用stmnt
并提取列,其中一部分是,
左右替换''||''
。