Plsql 处理运行时执行的多个查询的列列表。
我有一个存储在Oracle DB表中的查询列表。我的要求是逐个获取这些查询,并在一个过程中激发它们,并在另一个表中记录它们的开始-结束和运行时间 我的问题是我应该如何处理列列表,因为每个查询的列列表都会有所不同,并且在运行时无法预测列的数量及其数据类型 请建议一条出路 现在,我已经写下了下面的代码。在这里,我用count()括起了每个获取的查询,以避免出现问题。但是,count()查询的实际执行时间将不同于原始查询的执行时间 非常感谢Plsql 处理运行时执行的多个查询的列列表。,plsql,Plsql,我有一个存储在Oracle DB表中的查询列表。我的要求是逐个获取这些查询,并在一个过程中激发它们,并在另一个表中记录它们的开始-结束和运行时间 我的问题是我应该如何处理列列表,因为每个查询的列列表都会有所不同,并且在运行时无法预测列的数量及其数据类型 请建议一条出路 现在,我已经写下了下面的代码。在这里,我用count()括起了每个获取的查询,以避免出现问题。但是,count()查询的实际执行时间将不同于原始查询的执行时间 非常感谢 DECLARE before_time T
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;
声明
前时间戳;
后时间戳;
已用时间(单位:毫秒);
stmnt-CLOB--瓦查尔(32000);
计数数量;
sql_无编号;
err_mess VARCHAR2(100);
游标获取查询
是
从慢速运行的SQL中选择*,其中curr\u ind=1;
函数获取经过的时间(
时间戳中的开始时间,
结束时间(时间戳中的时间)
返回号码
作为
l_天数;
小时数;
分钟数;
秒数;
毫秒数;
开始
返回毫秒;
结束;
开始
dbms_output.put_行(当前_时间戳);
时间之前:=系统时间戳;
因为我有很多疑问
环
stmnt:=i.SQL\u DESC;
sql\u no:=i.sql\u no;
stmnt:=“从(“|| stmnt | |”)a”中选择计数(*);
dbms_output.put_line(stmnt);
立即执行stmnt计数;
_时间之后:=系统时间戳;
已用时间(单位:毫秒):=获取已用时间(时间前、时间后);
dbms_output.put_line(以毫秒为单位的运行时间);
插入
查询\u性能\u日志值
(
i、 不,
stmnt,
计数,
在这之前,
过了一段时间,
已用时间(单位:毫秒/1000),
“没有例外”,
已用时间(单位:毫秒);
dbms_output.put_line(stmnt);
dbms_输出。输入线(计数);
dbms_output.put_line(在_时间之后);
dbms_output.put_行(到_字符(在_时间之后-在_时间之前));
犯罪
端环;
回降;
例外情况
当其他人
err_mess:=SQLERRM;
插入
查询\u性能\u日志值
(
不,
stmnt,
0,
无效的
无效的
0,
呃,一团糟,
0
);
dbms_output.put_行(SQLERRM);
回降;
结束;
一个可能适合您的解决方案是为查询返回的每一行选择一个常量,并将批量收集到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;
如果您的查询选择的列是“简单”的,那么上面的操作应该足够公平,可以评估性能。但是,如果您开始为在选择中检索到的数据调用其他函数和过程,那么这将更加复杂
在另一种情况下,您应该尝试构建返回列的串联(并放大t_my_list
声明中的VARCHAR2(100)
)。这意味着您需要开始处理stmnt
并提取列,其中一部分是将、
替换为、
。适合您的解决方案是为查询返回的每一行选择一个常量,并将批量收集到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;
如果您的查询选择的列是“简单”的,那么上面的操作应该足够公平,可以评估性能。但是,如果您开始为在选择中检索到的数据调用其他函数和过程,那么这将更加复杂
在另一种情况下,您应该尝试构建返回列的串联(并放大t_my_list
声明中的VARCHAR2(100)
)。这意味着您要开始处理stmnt
并提取列,这是替换的一部分,
by“| |”
左右。一种解决方案可以是您可以将查询中使用的列串联起来,然后将结果获取到varchar字段一种解决方案可以是您可以将查询中使用的列串联起来,然后将结果获取到varchar字段非常感谢您的帮助。看起来列的串联更合适。不过,我们欢迎更多的建议。一个疑问是,与select*相比,所有行的批量收集是否会加快查询速度?我不希望这样,因为我需要记录查询的执行时间。大容量收集使您的代码检索每一行,而不是只检索一行进行计数。性能测试只检索计数与检索所有行是不同的。也许我真的不明白你打算做什么。非常感谢你的帮助。看起来列的串联更合适。不过,我们欢迎更多的建议。一个疑问是,与select*相比,所有行的批量收集是否会加快查询速度?我不希望这样,因为我需要记录查询的执行时间。大容量收集使您的代码检索每一行,而不是只检索一行进行计数。性能测试只检索计数与检索所有行是不同的。也许我真的不明白你打算做什么。