Plsql 处理运行时执行的多个查询的列列表。

Plsql 处理运行时执行的多个查询的列列表。,plsql,Plsql,我有一个存储在Oracle DB表中的查询列表。我的要求是逐个获取这些查询,并在一个过程中激发它们,并在另一个表中记录它们的开始-结束和运行时间 我的问题是我应该如何处理列列表,因为每个查询的列列表都会有所不同,并且在运行时无法预测列的数量及其数据类型 请建议一条出路 现在,我已经写下了下面的代码。在这里,我用count()括起了每个获取的查询,以避免出现问题。但是,count()查询的实际执行时间将不同于原始查询的执行时间 非常感谢 DECLARE before_time T

我有一个存储在Oracle DB表中的查询列表。我的要求是逐个获取这些查询,并在一个过程中激发它们,并在另一个表中记录它们的开始-结束和运行时间

我的问题是我应该如何处理列列表,因为每个查询的列列表都会有所不同,并且在运行时无法预测列的数量及其数据类型

请建议一条出路

现在,我已经写下了下面的代码。在这里,我用count()括起了每个获取的查询,以避免出现问题。但是,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;
声明
前时间戳;
后时间戳;
已用时间(单位:毫秒);
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*相比,所有行的批量收集是否会加快查询速度?我不希望这样,因为我需要记录查询的执行时间。大容量收集使您的代码检索每一行,而不是只检索一行进行计数。性能测试只检索计数与检索所有行是不同的。也许我真的不明白你打算做什么。